2012-03-24 10 views

Respuesta

16

Ver funciones all() y any() de las partes primera y segunda de sus preguntas, respectivamente. La función apply() se puede usar para ejecutar funciones sobre filas o columnas. (MARGIN = 1 es filas, MARGIN = 2 son columnas, etc.). Tenga en cuenta que uso apply() en df[, -1] para ignorar la variable id al hacer las comparaciones.

Parte 1:

> df <- data.frame(id=c(1:5), v1=c(0,15,9,12,7), v2=c(9,32,6,17,11)) 
> df[apply(df[, -1], MARGIN = 1, function(x) all(x > 10)), ] 
    id v1 v2 
2 2 15 32 
4 4 12 17 

Parte 2:

> df[apply(df[, -1], MARGIN = 1, function(x) any(x > 10)), ] 
    id v1 v2 
2 2 15 32 
4 4 12 17 
5 5 7 11 

Para ver lo que está pasando, x > 10 devuelve un vector lógico para cada fila (a través de apply() que indica si cada elemento es mayor que 10 all() devuelve TRUE if todos los elemento del vector de entrada son TRUE y FALSE de lo contrario any() devuelve TRUE if cualquier de los elementos en la entrada es TRUE y FALSE si todos son FALSE.

entonces utiliza el vector lógica resultante de la apply() llamada

> apply(df[, -1], MARGIN = 1, function(x) all(x > 10)) 
[1] FALSE TRUE FALSE TRUE FALSE 
> apply(df[, -1], MARGIN = 1, function(x) any(x > 10)) 
[1] FALSE TRUE FALSE TRUE TRUE 

al subconjunto df (como se muestra más arriba).

5

Esto se puede hacer usando apply con margen 1, que se aplicará una función para cada fila. La función para comprobar una fila dada sería

function(row) {all(row > 10)} 

Así que la manera de extraer las filas mismos es

df[apply(df, 1, function(row) {all(row > 10)}),] 
+0

+1 - y reemplace 'all' con' any' para la segunda pregunta. – flodel

+2

espera, quiere hacer 'all (row [-1]> 10)' para no dar cuenta de la columna 'id'. O aplique la función en 'df [-1]'. – flodel

0

Una opción es hacer bucles fila por fila (por ejemplo, con apply) y usar any o all, como se propone en las otras dos respuestas. Sin embargo, esto puede ser ineficiente para marcos de datos grandes.

Un enfoque vectorizado sería usar rowSums para determinar el número de valores en cada fila que coincida con su criterio, y el filtro basado en eso.

Al filtrar a las filas donde todo es al menos 10, este es el mismo como el filtrado a casos en que el número de valores de no más de 10 es 0:

df[rowSums(df[,-1] <= 10) == 0,] 
# id v1 v2 
# 2 2 15 32 
# 4 4 12 17 

mismo modo, rowSums fácilmente se puede utilizar para calcular las filas con cualquier cosa inferior o igual a 10:

df[rowSums(df[,-1] > 10) > 0,] 
# id v1 v2 
# 2 2 15 32 
# 4 4 12 17 
# 5 5 7 11 

El aumento de velocidad es clara con una entrada más grande:

set.seed(144) 
df <- matrix(sample(c(1, 10, 20), 3e6, replace=TRUE), ncol=3) 
system.time(df[apply(df[, -1], MARGIN = 1, function(x) all(x > 10)), ]) 
# user system elapsed 
# 1.754 0.156 2.102 
system.time(df[rowSums(df[,-1] <= 10) == 0,]) 
# user system elapsed 
# 0.04 0.01 0.05 
Cuestiones relacionadas