按重复次数对数据框进行子集化

6
如果我有一个这样的数据框:
neu <- data.frame(test1 = c(1,2,3,4,5,6,7,8,9,10,11,12,13,14), 
                  test2 = c("a","b","a","b","c","c","a","c","c","d","d","f","f","f"))
neu
   test1 test2
1      1     a
2      2     b
3      3     a
4      4     b
5      5     c
6      6     c
7      7     a
8      8     c
9      9     c
10    10     d
11    11     d
12    12     f
13    13     f
14    14     f

我希望只选择那些因子水平中出现次数超过三次的值,比如说test2,最快的方法是什么?

非常感谢,之前的问题没有找到合适的答案。

4个回答

7

使用以下方法查找行:

z <- table(neu$test2)[table(neu$test2) >= 3] # repeats greater than or equal to 3 times

或者:

z <- names(which(table(neu$test2)>=3))

然后使用以下子集:

subset(neu, test2 %in% names(z))

或者:

neu[neu$test2 %in% names(z),]

为什么要使用 as.list?为什么要使用两个 table(.)?最好不要使用 subset - Arun
请参见上面的替代策略。 - Thomas
1
@PatrickT subset 使用非标准评估,因此可能会产生意外结果。例如,如果您在函数内部使用它,它通常不会正常工作或根本不起作用。最好的建议是对于所有提取都使用 [ - Thomas
1
@PatrickT,当时我可能受到了这篇文章的影响。虽然那里有一些有效的观点,但只要你知道自己在做什么,我就不认为没有使用的理由。现在我倾向于避免建议“永远不要使用这个/那个”。 - Arun
谢谢你的链接,@Arun。听起来很可怕!你提供的问题/答案很好。 - PatrickT
显示剩余2条评论

5
这里还有另一种方法:
 with(neu, neu[ave(seq(test2), test2, FUN=length) > 3, ])

#   test1 test2
# 5     5     c
# 6     6     c
# 8     8     c
# 9     9     c

+1 这对我来说是目前为止最好的基础解决方案。 - Arun

3

我会使用plyr包中的count函数来进行计数:

library(plyr)
count_result = count(neu, "test2")
matching = with(count_result, test2[freq > 3])
with(neu, test1[test2 %in% matching])
[1] 5 6 8 9

2
更好的扩展性,使用 data.table 的方式:
library(data.table)
dt = data.table(neu)

dt[dt[, .I[.N >= 3], by = test2]$V1]

注意:希望未来以下更简单的语法将成为执行此操作的快速方式:
dt[, .SD[.N >= 3], by = test2]

(参见data.table下的按组子集


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