问题描述
这是一个错误报告,不是问题。报告R core中的错误的过程看起来很复杂,我不想成为邮件列表的一部分。因此,我要在此发布(如https://www.r-project.org/bugs.html.的建议)
这里是:
R 4.0.3的tapply()
帮助在参数X
上表示以下内容:
存在拆分方法的R对象。通常类似于矢量,允许使用[。
进行子集
问题:尽管可以拆分和子集化data.frame,但该R对象不能是data.frame。
要复制,请运行以下命令:
func <- function(dt) {
sum(dt[,1] * dt[,2])
}
tab <- data.frame(x = sample(100),y = sample(100),z = sample(letters[1:10],100,T))
tapply(tab[,1:2],INDEX = tab$z,FUN = func)
这导致
tapply(tab [,1:2],INDEX = tab $ z,FUN = func)中的错误: 参数必须具有相同的长度
在查看tapply()
源代码后,似乎是由以下检查导致的:
if (!all(lengths(INDEX) == length(X)))
stop("arguments must have same length")
但是length()
不是要调用data.frame以确定其是否具有合适的分割尺寸的相关函数。应该使用nrow()
。
将上面的代码替换为
if(is.data.frame(X)) {
len <- nrow(X)
} else {
len <- length(X)
}
if (!all(lengths(INDEX) == len))
stop("arguments must have same length")
此修补程序看起来非常简单,实现该修补程序将大大提高tapply()
的实用性(我知道tapply()
会有很多强大的选择),所以我想知道当前的限制是否反映了一种设计选择。
解决方法
基于功能,我们可以使用
library(dplyr)
tab %>%
group_by(z) %>%
summarise(new = func(cur_data()),.groups = 'drop')
-输出
# A tibble: 10 x 2
# z new
# <chr> <int>
# 1 a 26647
# 2 b 28010
# 3 c 31340
# 4 d 20780
# 5 e 33311
# 6 f 31880
# 7 g 37527
# 8 h 8752
# 9 i 15490
或使用by
中的base R
by(tab[,1:2],tab$z,FUN = func)
根据?tapply
X-一个存在拆分方法的R对象。通常类似于矢量,允许使用[。
进行子集
此处,tab[,1:2]
是一个数据帧,而不是vector
。如果它是matrix
,它将是具有vector
属性的dim