由于长度检查不正确,R tapply() 在 data.frame 上不起作用

R tapply() does not work on data.frame due to improper length check

提问人:jeanlain 提问时间:10/12/2020 更新时间:10/12/2020 访问量:425

问:

这是一个错误报告,而不是一个问题。在 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()

R DataFrame tapply

评论

0赞 akrun 10/12/2020
length在 Data.Frame 上,上下文是 。上面显示的函数更适合 而不是 。ncolbytapply

答:

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

或使用 frombybase R

by(tab[, 1:2], tab$z, FUN = func)

根据?tapply

X - 存在拆分方法的 R 对象。通常类似向量,允许使用 [.

这里,是一个 data.frame,而不是一个 .如果它是 ,它将是具有属性的tab[, 1:2]vectormatrixvectordim

评论

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?tapplyX
0赞 jeanlain 10/12/2020
tapply不希望是 data.frame,它与我正在应用的函数无关。我想知道这个限制的意义。X
0赞 akrun 10/12/2020
@jeanlain 在这里,X 是一个 data.frame,您的函数将参数作为 data.frame。不清楚你的评论tab[1:2]