导致长度不等于 1 或 dplyr 中组长度的分组操作
Posted
技术标签:
【中文标题】导致长度不等于 1 或 dplyr 中组长度的分组操作【英文标题】:grouped operations that result in length not equal to 1 or length of group in dplyr 【发布时间】:2014-03-11 08:41:04 【问题描述】:我不确定使用哪个函数来执行以下操作:
library(data.table)
dt = data.table(a = 1:4, b = 1:2)
dt[, rep(a[1], 3), by = b]
# b V1
#1: 1 1
#2: 1 1
#3: 1 1
#4: 2 2
#5: 2 2
#6: 2 2
summarise
和 mutate
都不满意这个长度:
library(dplyr)
df = data.frame(a = 1:4, b = 1:2)
df %.% group_by(b) %.% summarise(rep(a[1], 3))
#Error: expecting a single value
df %.% group_by(b) %.% mutate(rep(a[1], 3))
#Error: incompatible size (3), expecting 2 (the group size) or 1
【问题讨论】:
不知道是否有帮助,但使用dplyr
代码和 data.table
可以工作,而 plyr
你也可以使用 data.frame
来做到这一点。
@dickoa 谢谢,这很有趣(fwiw 这主要是让我了解如何使用dplyr
的练习——我真的不明白将它与data.table
一起使用的意义) ;听起来像summarise
中的一个错误然后
见github.com/hadley/dplyr/issues/154
+1 这是一个有趣的区别;希望最终解决方案允许任何组的任意返回长度。
在这种情况下df %>% group_by(b) %>% slice(rep(1, 3))
工作正常。对于每行返回任意数量的值的逐行操作,您可以使用 df %>% mutate(new = map(old, f)) %>% unnest()
成语。
【参考方案1】:
在dplyr
0.2 版中,您可以使用do
运算符来执行此操作:
> df %>% group_by(b) %>% do(data.frame(a = rep(.$a[1], 3)))
#Source: local data frame [6 x 2]
#Groups: b
#
# b a
#1 1 1
#2 1 1
#3 1 1
#4 2 2
#5 2 2
#6 2 2
【讨论】:
+1 向我展示了do
可以做什么(尽管请注意我的“答案”中的 cmets)【参考方案2】:
虽然@beginneR 的回答确实有效,但它似乎并不能真正替代data.table
行为。考虑:
df <- data.frame(a = 1, b = rep(1:1e4, 2))
dt <- data.table(df)
microbenchmark(times=5,
dt[, rep(a[1], 3), by = b],
df %>% group_by(b) %>% do(data.frame(a = rep(.$a[1], 3)))
)
dplyr
的实现速度慢了 200 倍。
Unit: milliseconds
expr min lq median uq
dt[, rep(a[1], 3), by = b] 13.14318 13.70248 14.60524 15.26676
df %>% group_by(b) %>% do(data.frame(a = rep(.$a[1], 3))) 3269.40731 3359.11614 3583.19430 3736.67162
也许有更好的方法来使用do
而不需要调用data.frame
每个do
?此外,data.table
中非常简单的东西的语法有点涉及。
否则,根据 Hadley's issue link,这似乎有望在 3.1 中的 dplyr
中实现,这看起来是下一个版本。
【讨论】:
以上是关于导致长度不等于 1 或 dplyr 中组长度的分组操作的主要内容,如果未能解决你的问题,请参考以下文章
R:错误:在 dplyr 中使用 unnest 时长度不兼容
POJ 3415 Common Substrings(长度不小于K的公共子串的个数+后缀数组+height数组分组思想+单调栈)