R vector numérico dividido en posición

Me pregunto acerca de la simple tarea de dividir un vector en dos en un índice determinado:

splitAt <- function(x, pos){ list(x[1:pos-1], x[pos:length(x)]) } a  splitAt(a, 4) [[1]] [1] 1 2 2 [[2]] [1] 3 

Mi pregunta: debe haber alguna función existente para esto, ¿pero no puedo encontrarla? ¿Tal vez se split una posibilidad? Mi implementación ingenua tampoco funciona si pos=0 o pos>length(a) .

Una mejora sería:

 splitAt <- function(x, pos) unname(split(x, cumsum(seq_along(x) %in% pos))) 

que ahora puede tomar un vector de posiciones:

 splitAt(a, c(2, 4)) # [[1]] # [1] 1 # # [[2]] # [1] 2 2 # # [[3]] # [1] 3 

Y se comporta correctamente (subjetivo) si pos <= 0 o pos >= length(x) en el sentido de que devuelve el vector original completo en un solo elemento de la lista. Si prefieres un error, utiliza stopifnot en la parte superior de la función.

Traté de usar la respuesta de Flodel , pero fue demasiado lento en mi caso con una x muy grande (y la función tiene que ser llamada repetidamente). Así que creé la siguiente función que es mucho más rápida, pero también muy fea y no se comporta correctamente. En particular, no verifica nada y arrojará resultados defectuosos al menos para pos >= length(x) o pos <= 0 (puede agregar esos controles usted mismo si no está seguro acerca de sus entradas y no está demasiado preocupado por la velocidad ), y tal vez algunos otros casos también, así que ten cuidado.

 splitAt2 <- function(x, pos) { out <- list() pos2 <- c(1, pos, length(x)+1) for (i in seq_along(pos2[-1])) { out[[i]] <- x[pos2[i]:(pos2[i+1]-1)] } return(out) } 

Sin embargo, splitAt2 ejecuta aproximadamente 20 veces más rápido con una x de longitud 10 6 :

 library(microbenchmark) W <- rnorm(1e6) splits <- cumsum(rep(1e5, 9)) tm <- microbenchmark( splitAt(W, splits), splitAt2(W, splits), times=10) tm 

Otra alternativa que podría ser más rápida y / o más legible / elegante que la solución de Flodel :

 splitAt <- function(x, pos) { unname(split(x, findInterval(x, pos))) } 
    Intereting Posts