导致长度不等于 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

summarisemutate 都不满意这个长度:

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 中组长度的分组操作的主要内容,如果未能解决你的问题,请参考以下文章

总结但保持长度可变(dplyr)

R:错误:在 dplyr 中使用 unnest 时长度不兼容

分组符号最大长度平衡子序列

POJ 3415 Common Substrings(长度不小于K的公共子串的个数+后缀数组+height数组分组思想+单调栈)

geosphere distHaversine() & dplyr - 错误向量长度错误,应该是 2

如果最长的表的长度大于或等于 5,如何将每个表的长度更改为等于最长的表?