2015-07-03 101 views
5

假设我有以下的数据帧(实际的一个代表非常大的数据集)匹配值基于组ID

df<- structure(list(x = c(1, 1, 1, 2, 2, 3, 3, 3), y = structure(c(1L, 
6L, NA, 2L, 4L, 3L, 7L, 5L), .Label = c("all", "fall", "hello", 
"hi", "me", "non", "you"), class = "factor"), z = structure(c(5L, 
NA, 4L, 2L, 1L, 6L, 3L, 4L), .Label = c("fall", "hi", "me", "mom", 
"non", "you"), class = "factor")), .Names = c("x", "y", "z"), row.names = c(NA, 
-8L), class = "data.frame") 

它看起来像

>df 
    x  y z 
1 1 all non 
2 1 non <NA> 
3 1 <NA> mom 
4 2 fall hi 
5 2 hi fall 
6 3 hello you 
7 3 you me 
8 3 me mom 

我所试图做的是计算每组x(1,2或3)中匹配值的数量。例如,组号1有一个匹配值,即"non"(NA应该被忽略)。所需的输出看起来像:

x n 
1 1 1 
2 2 2 
3 3 2 

试图想在做这个,而不是for-loop,因为我有一个大的数据集的方式,但无法通过找到我的路。

回答

5

使用dplyr

library(dplyr) 

df %>% group_by(x) %>% 
     summarise(n = sum(y %in% na.omit(z))) 
+0

真的不知道为什么它不给我所需的输出。它给了我'n 1 5' – athraa

+1

@AhmedSalhin适合我。也许'plyr'干扰。我认为这些软件包有一些不兼容性,具体取决于它们的加载顺序。 – Frank

+0

@Frank是的,你是对的。我把'plyr'分开了,它适用于我。你知道如何克服这个干扰问题吗? – athraa

3

下面是使用by()match()一个解决方案:

do.call(rbind,by(df,df$x,function(g) c(x=g$x[1],n=sum(!is.na(match(g$y,g$z,inc=NA)))))); 
## x n 
## 1 1 1 
## 2 2 2 
## 3 3 2 
+2

我喜欢这个基础R解决方案......说实话,我的是长和笨拙,我更喜欢这一个。投票! – SabDeM

4

只是为了每夜乐趣我已经尝试了基础R解决方案,这当然是丑得要命。

ind <- by(df, df$x, function(x) which(na.omit(x[["y"]]) %in% na.omit(df[["z"]]))) 
sm <- lapply(ind, length) 
cbind(unique(df$x), sm) 
sm 
1 1 1 
2 2 2 
3 3 2 

另一个基础R方法,用更少的代码(和更少的丑陋,我希望):

ind <- by(df, df$x, function(x) sum(na.omit(x[["y"]]) %in% na.omit(x[["z"]]))) 
cbind(unique(df$x), ind) 
    ind 
1 1 1 
2 2 2 
3 3 2