我有一个包含两列以上的数据框。
d <- data.frame(
a=c(1, 1, 2, 2),
b=c(T, T, T, F),
c=c(0, 0.25, 0.5, 0.75),
d=c("a", "b", "c", "d")
)
我想对&#34; d&#34;的行进行分组。通过列&#34; a&#34;和&#34; b&#34;,然后对列进行操作&#34; c&#34;和&#34; d&#34;。但是,当我使用by
时,我会得到对应于未出现在&#34; d&#34;中的组合的空条目。
by(d, list(d$a, d$b), nrow)
# : 1
# : FALSE
# [1] NA
# ------------------------------------------------------------
# : 2
# : FALSE
# [1] 1
# ------------------------------------------------------------
# : 1
# : TRUE
# [1] 2
# ------------------------------------------------------------
# : 2
# : TRUE
# [1] 1
我想要的是没有空单元格对应于a = 1且b = FALSE:
的结果# : 2
# : FALSE
# [1] 1
# ------------------------------------------------------------
# : 1
# : TRUE
# [1] 2
# ------------------------------------------------------------
# : 2
# : TRUE
# [1] 1
在这个例子中,我只是使用nrow
,但实际上我需要&#34; c&#34;和&#34; d&#34;对于该函数,我真的需要by
而不是tapply
(尽管如果有人知道如何使用tapply
执行此操作,那也是受欢迎的)。我不想在事后过滤by
对象,因为我的数据非常大。
答案 0 :(得分:4)
将interaction
与drop=TRUE
:
by(d, list(group=interaction(d$a,d$b,drop=TRUE)), nrow)
#group: 2.FALSE
#[1] 1
#------------------------------------------------------
#group: 1.TRUE
#[1] 2
#-------------------------------------------------------
#group: 2.TRUE
#[1] 1
答案 1 :(得分:2)
这给出了一个数据帧,除了NA单元之外,每个单元有一行。 bb
是by
:
> na.omit(as.data.frame.table(bb))
a b Freq
2 2 FALSE 1
3 1 TRUE 2
4 2 TRUE 1
这是否适用于其他功能取决于它们返回的内容。
在评论中,海报澄清说他们不想减少by
的结果,而是取代by
。在这种情况下,请尝试aggregate
:
ix <- 1:nrow(d)
aggregate(ix ~ a+b, d, function(ix) nrow(d[ix, ]))
,并提供:
a b ix
1 2 FALSE 1
2 1 TRUE 2
3 2 TRUE 1
在这种特殊情况下,我们可以使用length
来代替函数,但是我们以这种形式显示它,因为它依赖于d[ix, ]
因此可能是任意复杂的并且可能取决于任何或所有列。
答案 2 :(得分:1)
您可以将data.table
用于大数据集
library(data.table)
setDT(d)[, .N, by=list(a,b)]
# a b N
#1: 1 TRUE 2
#2: 2 TRUE 1
#3: 2 FALSE 1
或者
setorder(setDT(d), a,b) #would be faster
d[, .N, by=list(a,b)]
# a b N
#1: 1 TRUE 2
#2: 2 FALSE 1
#3: 2 TRUE 1