2016-08-08 20 views
3

Ich habe diese data.frame mit vieler NAs:r Teilmenge Reihen von Kriterien und durch Faktorgruppe

df <- data.frame(a = rep(letters[1:3], each = 3), 
       b = c(NA, NA, NA, 1, NA, 3, NA, NA, 7)) 
df 
> df 
    a b 
1 a NA 
2 a NA 
3 a NA 
4 b 1 
5 b NA 
6 b 3 
7 c NA 
8 c NA 
9 c 7 

Ich mag diesen Datenrahmen der Teilmenge nur Faktor Gruppenzeilen zu erhalten, die keine hat weniger als zwei diese Werte, wie zum Beispiel:

a b 
1 b 1 
2 b NA 
3 b 3 

ich habe diese Funktion versucht, aber es funktioniert nicht:

subset(df, sum(!is.na(b)) < 1, by = a) 

> [1] a b 
<0 rows> (or 0-length row.names) 

Irgendwelche sugges tion? (andere Pakete Lösungen sind willkommen)

Antwort

2

Wir können data.table verwenden. Wandle den 'data.frame' in 'data.table' um (setDT(df)), gruppiert nach 'a', if der sum des logischen Vektors (d. H. Nicht-NA-Elemente - !is.na(b)) ist größer als 1, dann Subset the Data.table.

library(data.table) 
setDT(df)[,if(sum(!is.na(b))>1) .SD , by = a] 
# a b 
#1: b 1 
#2: b NA 
#3: b 3 

Oder dplyr, mit der gleichen Logik, nach der durch 'a' Gruppierung, filter wir die Zeilen.

library(dplyr) 
df %>% 
    group_by(a) %>% 
    filter(sum(!is.na(b))>1) 
#  a  b 
# <fctr> <dbl> 
#1  b  1 
#2  b NA 
#3  b  3 

Oder in base R mit ave

df[with(df, ave(b, a, FUN = function(x) sum(!is.na(x))>1)!=0),] 
0

Ein Weg verwendet aggregate. Zähle die Anzahl der Elemente, die nicht NA sind, für jede eindeutige a und setze dann diese Zeilen aus dem Datenrahmen sub unter.

agg <- aggregate(b~a, df, function(x) length(!is.na(x)) >= 2) 
df[df$a %in% agg[agg$b, "a"], ] 

# a b 
#4 b 1 
#5 b NA 
#6 b 3 

Eine weitere Option table verwendet.

df[df$a %in% names(which(table(df$a, is.na(df$b))[,1] > 1)), ] 


# a b 
#4 b 1 
#5 b NA 
#6 b 3 
Verwandte Themen