基于频率水平进行子集筛选

3
我想生成一个数据框,它选择与名为cutoff的变量相关联的“ID”所关联的行。在本例中,我将cutoff设置为9,这意味着我要选择df1中与超过9行相关联的ID值所关联的行。我的代码的最后一行生成了一个我不理解的数据框。正确的数据框应该有24行,所有行的ID列都是3或4。可以有人解释一下我的最后一行代码实际在做什么,并提出不同的方法吗?
set.seed(123)
ID<-rep(c(1,2,3,4,5),times=c(5,7,9,11,13))
sub1<-rnorm(45)
sub2<-rnorm(45)
df1<-data.frame(ID,sub1,sub2)
IDfreq<-count(df1,"ID")
cutoff<-9
df2<-subset(df1,subset=(IDfreq$freq>cutoff))

1
count不是基本的R函数。您在subset()内部使用的子集参数也不应该使用$ - IRTFM
3个回答

6
df1[ df1$ID %in%  names(table(df1$ID))[table(df1$ID) >9] , ]

这将测试df1$ID值是否属于超过9个值的类别。如果是,则返回向量的逻辑元素将为TRUE,进而作为“i”参数导致[-函数返回整行,因为“j”项为空。

参见:

?`[`
?'%in%'

谢谢,这个完美地解决了问题。我查看了您推荐的帮助文档,但是还没有完全理解。我对名称和表格的作用感到困惑。您能否推荐一种更适合初学者的好的在线资源? - user3614783
我不确定混淆出现在哪里。如果您有一个一维表,则“names”属性的值也是一维的,即R向量。因此,任务是选择其中一个(或多个)字符值与满足逻辑测试中设置的数值内部(计数)相关联的那些值。table(df1$ID)> 9。这样,左侧表达式的工作就完成了。 - IRTFM

6
使用 dplyr
library(dplyr)
 df1 %>% 
 group_by(ID) %>% 
 filter(n()>cutoff)

5
也许更接近您所想的是使用ave创建频率向量:
subset(df1, ave(ID, ID, FUN = length) > cutoff)

我知道加上 +1 的评论不被鼓励,但是这个评论实在是太优美了,让人难以抵制。 - IRTFM
谢谢,这也可以工作,我喜欢它的紧凑性。但是您能解释一下这两个ID参数如何协同工作吗?以及ave如何对其后面的内容起作用? R文档说,这是对具有相同因子水平的观测子集进行平均处理。为什么要平均处理呢? - user3614783
第一个ID只是一个标记,用于计算每个ID因子水平中有多少项。 - IRTFM
ave(arg1, arg2, FUN = length) 本质上是使用 arg2 对数据进行分组,然后对每个分组计算 length(arg1),最后将结果放回到一个向量中。因此,ave(ID, ID, FUN = length) 实际上为您提供了每行在整个 ID 列中出现次数的数量。为了帮助您理解,您可以分两步完成:df1 <- transform(df1, freq = ave(ID, ID, FUN = length)); print(df1); subset(df1, freq > cutoff); - flodel
这很有帮助。我是R的新手,从来没有想过看这个。文档说ave可以对组进行平均。 - user3614783

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接