una - seleccionar columnas en r
R-forma más rápida de seleccionar las filas de una matriz que satisfacen múltiples condiciones (4)
Úselo con arr.ind=TRUE
como en:
> mat[which(mat[,"two"]==7 & mat[,"three"] == 12, arr.ind = TRUE),]
one two three four
2 2 7 12 17
7 5 7 12 20
Esta es una extensión de la pregunta sobre cómo devolver las filas de una matriz que cumplen una condición en R. Digamos que tengo la matriz:
one two three four
[1,] 1 6 11 16
[2,] 2 7 12 17
[3,] 3 8 11 18
[4,] 4 9 11 19
[5,] 5 10 15 20
[6,] 1 6 15 20
[7,] 5 7 12 20
Quiero devolver todas las filas, donde la matrix$two == 7
Y la matrix$three == 12
más rápido posible. Esta es la manera en que sé hacerlo:
out <- mat[mat$two == 7,]
final_out <- out[out$three == 12, ]
Obviamente debería haber un método para obtener los contenidos de final_out
en una línea, algo así como: final_out <- which(mat$two == 7 && mat$three == 12)
que es más rápido y más breve que las dos líneas de los códigos anteriores.
¿Cuál es el código R más rápido para devolver esta consulta de matriz de condición múltiple?
Simplemente use [
subconjunto con comparación lógica ...
# Reproducible data
set.seed(1)
m <- matrix( sample(12,28,repl=T) , 7 , 4 )
[,1] [,2] [,3] [,4]
[1,] 4 8 10 3
[2,] 5 8 6 8
[3,] 7 1 9 2
[4,] 11 3 12 4
[5,] 3 3 5 5
[6,] 11 9 10 1
[7,] 12 5 12 5
# Subset according to condition
m[ m[,2] == 3 & m[,3] == 12 , ]
[1] 11 3 12 4
la manera más rápida en R será ifelse
que a diferencia de if
permite condicionales vectorizados. También puede almacenar en caché los vectores de condicionales (por ejemplo, isSeven <- mat[, ''two''] == 7
) y usar / reutilizarlos más tarde.
No tengo un ejemplo reproducible aquí, pero haría algo así como
ifelse(mat[, ''two''] == 7 & mat[, ''three''] == 12, "both", "not both")
Puedes desplazar otros elementos condicionales allí o hacer que devuelva algo que genere un vector conforme.
ACTUALIZACIÓN CON MICROBENCHMARK:
Usar el punto de referencia da la respuesta opuesta. Parece que la respuesta dada por @ SimonO101 proporciona una implementación ligeramente más rápida.
require(microbenchmark)
set.seed(1)
m <- matrix( sample(12,100,repl=T) , 25 , 4 )
colnames(m) <- c("one","two","three","four")
bench1 <- microbenchmark(m[which(m[,''two'']==7 & m[,''three''] == 12, arr.ind = TRUE),])
summary(bench1$time)
Min. 1st Qu. Median Mean 3rd Qu. Max.
7700 8750 9449 9688 9800 22400
bench2 <- microbenchmark(m[ m[,2] == 3 & m[,3] == 12 , ])
summary(bench2$time)
Min. 1st Qu. Median Mean 3rd Qu. Max.
6300 7350 7351 7599 8050 15400
ANTIGUA RESPUESTA:
La combinación de las respuestas dadas por @Jiber y @ SimonO101 da una respuesta ligeramente más rápida, al menos en mi computadora.
Hice la matriz mucho más grande para separar los tiempos de cálculo.
set.seed(1)
m <- matrix( sample(12,1000000000,repl=T) , 1e8 , 10 )
colnames(m) <- c("one","two","three","four","five","six","seven","eight","nine","ten")
system.time(m[which(m[,''two'']==7 & m[,''three''] == 12, arr.ind = TRUE),])
user system elapsed
6.49 1.58 8.06
system.time(m[ m[,2] == 3 & m[,3] == 12 , ])
user system elapsed
8.23 1.29 9.52
Esto obviamente supone que las columnas de la matriz son nombradas.