提问人:jeanlain 提问时间:10/12/2020 更新时间:10/12/2020 访问量:425
由于长度检查不正确,R tapply() 在 data.frame 上不起作用
R tapply() does not work on data.frame due to improper length check
问:
这是一个错误报告,而不是一个问题。在 R 核心中报告错误的过程看起来很复杂,我不想成为邮件列表的一部分。所以我在这里发布这个(按照 https://www.r-project.org/bugs.html 的建议。)
在这里:
R 4.0.3 的帮助在论证上说了以下几点:tapply()
X
存在拆分方法的 R 对象。通常类似向量,允许使用 [.
问题:此 R 对象不能是 data.frame,但 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")
但不是调用 data.frame 以确定它是否具有适合拆分的维度的相关函数。 应该改用。length()
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()
答:
1赞
akrun
10/12/2020
#1
基于函数,我们可以使用
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
或使用 fromby
base R
by(tab[, 1:2], tab$z, FUN = func)
根据?tapply
X - 存在拆分方法的 R 对象。通常类似向量,允许使用 [.
这里,是一个 data.frame,而不是一个 .如果它是 ,它将是具有属性的tab[, 1:2]
vector
matrix
vector
dim
评论
0赞
jeanlain
10/12/2020
好的,所以这似乎是 data.frames 的等价物。但是为什么不在data.frame上工作呢?by()
tapply()
tapply
0赞
akrun
10/12/2020
@jeanlain约束是你创建函数的方式,而不是预期的方式tapply
0赞
akrun
10/12/2020
@jeanlain它不是你提到的错误。如果选中 ,则它应为向量,而函数应为 data.frame?tapply
X
0赞
jeanlain
10/12/2020
tapply
不希望是 data.frame,它与我正在应用的函数无关。我想知道这个限制的意义。X
0赞
akrun
10/12/2020
@jeanlain 在这里,X 是一个 data.frame,您的函数将参数作为 data.frame。不清楚你的评论tab[1:2]
评论
length
在 Data.Frame 上,上下文是 。上面显示的函数更适合 而不是 。ncol
by
tapply