2011-08-18 15 views
16

I tienen una trama de datos por ejemplo .:Eliminación de filas específicas de una trama de datos

sub day 
1  1 
1  2 
1  3 
1  4 
2  1 
2  2 
2  3 
2  4 
3  1 
3  2 
3  3 
3  4 

y me gustaría para eliminar filas específicas que pueden ser identificados por la combinación de sub y día. Por ejemplo, decir que quería eliminar filas donde sub = '1' y día = '2' y sub = 3 y día = '4'. ¿Cómo podría hacer esto? Me doy cuenta de que podría especificar los números de fila, pero esto debe aplicarse a un enorme marco de datos que sería tedioso de recorrer e identificar cada fila.

Respuesta

27
DF[ ! ((DF$sub ==1 & DF$day==2) | (DF$sub ==3 & DF$day==4)) , ] # note the ! (negation) 

O si sub es una factor según lo sugerido por el uso de las cotizaciones:

DF[ ! paste(sub,day,sep="_") %in% c("1_2", "3_4"), ] 

También es posible usar subconjunto:

subset(DF, ! paste(sub,day,sep="_") %in% c("1_2", "3_4")) 

(. Y apoyar el uso de which en la respuesta de Dirk cuando se utiliza "[" a pesar de que algunos afirman que no es necesario)

+0

Ese es el boleto. Gracias. ¿Qué significa% en%? –

+2

Es un ejemplo de un operador infijo y devuelve un vector lógico que le indica cuáles de los elementos en el primer argumento están contenidos en el segundo argumento. Ver? Partido donde está definido. –

+0

@BondedDust y aquí también –

16

esto se reduce a dos etapas distintas:

  1. Figura cabo cuando su condición es verdadera, y por lo tanto calcular un vector de booleanos, o, como yo prefiero, sus índices envolviéndolo en which()
  2. Cree un data.frame actualizado excluyendo los índices del paso anterior.

Aquí se muestra un ejemplo:

R> set.seed(42) 
R> DF <- data.frame(sub=rep(1:4, each=4), day=sample(1:4, 16, replace=TRUE)) 
R> DF 
    sub day 
1 1 4 
2 1 4 
3 1 2 
4 1 4 
5 2 3 
6 2 3 
7 2 3 
8 2 1 
9 3 3 
10 3 3 
11 3 2 
12 3 3 
13 4 4 
14 4 2 
15 4 2 
16 4 4 
R> ind <- which(with(DF, sub==2 & day==3)) 
R> ind 
[1] 5 6 7 
R> DF <- DF[ -ind, ] 
R> table(DF) 
    day 
sub 1 2 3 4 
    1 0 1 0 3 
    2 1 0 0 0 
    3 0 1 3 0 
    4 0 2 0 2 
R> 

y vemos que sub==2 tiene sólo una entrada restante con day==1.

Editar La condición compuesto se puede hacer con un 'o' como sigue:

ind <- which(with(DF, (sub==1 & day==2) | (sub=3 & day=4))) 

y aquí es un nuevo ejemplo completo

R> set.seed(1) 
R> DF <- data.frame(sub=rep(1:4, each=5), day=sample(1:4, 20, replace=TRUE)) 
R> table(DF) 
    day 
sub 1 2 3 4 
    1 1 2 1 1 
    2 1 0 2 2 
    3 2 1 1 1 
    4 0 2 1 2 
R> ind <- which(with(DF, (sub==1 & day==2) | (sub==3 & day==4))) 
R> ind 
[1] 1 2 15 
R> DF <- DF[-ind, ] 
R> table(DF) 
    day 
sub 1 2 3 4 
    1 1 0 1 1 
    2 1 0 2 2 
    3 2 1 1 0 
    4 0 2 1 2 
R> 
+0

bien, creo que va a trabajar con un poco de ayuda extra ... i necesidad de identificación entify multiple days así que probé su código ligeramente modificado: ind <-which (with (Licor, day = c ('1', '16', '30', '37', '51', '52', '57 ', '58'))) pero recibe un mensaje de error. ¿Algunas ideas? –

+0

Trabaja en la expresión para calcular los indies, puedes encontrar 'help (match)' útil. –

+0

Esta respuesta tiene una explicación sobre la estrategia necesaria, cómo aplicar el código y qué código aplicar, con ejemplos. Esto fue útil. – Irwin

4

Aquí es una solución a su problema al utilizar la función dplyrfilter.

Aunque puede pasar su marco de datos como primer argumento a cualquier función dplyr, he usado su operador %>%, que canaliza su marco de datos a una o más funciones dplyr (solo filtro en este caso).

Una vez que esté familiarizado con dplyr, el cheat sheet es muy útil.

> print(df <- data.frame(sub=rep(1:3, each=4), day=1:4)) 
    sub day 
1 1 1 
2 1 2 
3 1 3 
4 1 4 
5 2 1 
6 2 2 
7 2 3 
8 2 4 
9 3 1 
10 3 2 
11 3 3 
12 3 4 
> print(df <- df %>% filter(!((sub==1 & day==2) | (sub==3 & day==4)))) 
    sub day 
1 1 1 
2 1 3 
3 1 4 
4 2 1 
5 2 2 
6 2 3 
7 2 4 
8 3 1 
9 3 2 
10 3 3 
2

una solución simple

cond1 <- df$sub == 1 & df$day == 2

cond2 <- df$sub == 3 & df$day == 4

df <- df[!cond1,]

df <- df[!cond2,]

Cuestiones relacionadas