gpt4 book ai didi

r - 使用 tapply 按组对多列求和

转载 作者:行者123 更新时间:2023-12-03 23:26:26 27 4
gpt4 key购买 nike

我想按组汇总各个列,我的第一个想法是使用 tapply .
但是,我无法获得 tapply上类。可以 tapply用于对多列求和?
如果没有,为什么不呢?

我广泛搜索了互联网,发现发布了许多类似的问题
早在 2008 年。然而,这些问题都没有得到直接回答。
相反,响应总是建议使用不同的函数。

下面是一个示例数据集,我希望按州对苹果、按州对樱桃求和
和李子按州。在此之下,我编写了许多 tapply 的替代方案。那
做工作。

在底部,我展示了对 tapply 的简单修改。允许的源代码tapply以执行所需的操作。

尽管如此,也许我忽略了执行所需操作的简单方法
tapply .我不是在寻找替代功能,尽管欢迎其他替代功能。

鉴于我对 tapply 的修改很简单源代码我想知道为什么它,或者
类似的东西,尚未实现。

谢谢你的任何建议。如果我的问题是重复的,我很乐意发布我的
问题作为另一个问题的答案。

这是示例数据集:

df.1 <- read.table(text = '

state county apples cherries plums
AA 1 1 2 3
AA 2 10 20 30
AA 3 100 200 300
BB 7 -1 -2 -3
BB 8 -10 -20 -30
BB 9 -100 -200 -300

', header = TRUE, stringsAsFactors = FALSE)

这不起作用:
tapply(df.1, df.1$state, function(x) {colSums(x[,3:5])})

帮助页面说:
tapply(X, INDEX, FUN = NULL, ..., simplify = TRUE)

X an atomic object, typically a vector.

我被短语 typically a vector 弄糊涂了这让我想知道是否
可以使用数据框。我一直不清楚是什么 atomic object方法。

以下是 tapply 的几种替代方案确实有效。第一个选择是结合 tapply 的变通方法。与 apply .
apply(df.1[,c(3:5)], 2, function(x) tapply(x, df.1$state, sum))

# apples cherries plums
# AA 111 222 333
# BB -111 -222 -333

with(df.1, aggregate(df.1[,3:5], data.frame(state), sum))

# state apples cherries plums
# 1 AA 111 222 333
# 2 BB -111 -222 -333

t(sapply(split(df.1[,3:5], df.1$state), colSums))

# apples cherries plums
# AA 111 222 333
# BB -111 -222 -333

t(sapply(split(df.1[,3:5], df.1$state), function(x) apply(x, 2, sum)))

# apples cherries plums
# AA 111 222 333
# BB -111 -222 -333

aggregate(df.1[,3:5], by=list(df.1$state), sum)

# Group.1 apples cherries plums
# 1 AA 111 222 333
# 2 BB -111 -222 -333

by(df.1[,3:5], df.1$state, colSums)

# df.1$state: AA
# apples cherries plums
# 111 222 333
# ------------------------------------------------------------
# df.1$state: BB
# apples cherries plums
# -111 -222 -333

with(df.1,
aggregate(x = list(apples = apples,
cherries = cherries,
plums = plums),
by = list(state = state),
FUN = function(x) sum(x)))

# state apples cherries plums
# 1 AA 111 222 333
# 2 BB -111 -222 -333

lapply(split(df.1, df.1$state), function(x) {colSums(x[,3:5])} )

# $AA
# apples cherries plums
# 111 222 333
#
# $BB
# apples cherries plums
# -111 -222 -333

这是 tapply的源代码除了我改变了这一行:
nx <- length(X)

到:
nx <- ifelse(is.vector(X), length(X), dim(X)[1])
tapply的这个修改版执行所需的操作:
my.tapply <- function (X, INDEX, FUN = NULL, ..., simplify = TRUE)
{
FUN <- if (!is.null(FUN)) match.fun(FUN)
if (!is.list(INDEX)) INDEX <- list(INDEX)
nI <- length(INDEX)
if (!nI) stop("'INDEX' is of length zero")
namelist <- vector("list", nI)
names(namelist) <- names(INDEX)
extent <- integer(nI)
nx <- ifelse(is.vector(X), length(X), dim(X)[1]) # replaces nx <- length(X)
one <- 1L
group <- rep.int(one, nx) #- to contain the splitting vector
ngroup <- one
for (i in seq_along(INDEX)) {
index <- as.factor(INDEX[[i]])
if (length(index) != nx)
stop("arguments must have same length")
namelist[[i]] <- levels(index)#- all of them, yes !
extent[i] <- nlevels(index)
group <- group + ngroup * (as.integer(index) - one)
ngroup <- ngroup * nlevels(index)
}
if (is.null(FUN)) return(group)
ans <- lapply(X = split(X, group), FUN = FUN, ...)
index <- as.integer(names(ans))
if (simplify && all(unlist(lapply(ans, length)) == 1L)) {
ansmat <- array(dim = extent, dimnames = namelist)
ans <- unlist(ans, recursive = FALSE)
} else {
ansmat <- array(vector("list", prod(extent)),
dim = extent, dimnames = namelist)
}
if(length(index)) {
names(ans) <- NULL
ansmat[index] <- ans
}
ansmat
}

my.tapply(df.1$apples, df.1$state, function(x) {sum(x)})

# AA BB
# 111 -111

my.tapply(df.1[,3:4] , df.1$state, function(x) {colSums(x)})

# $AA
# apples cherries
# 111 222
#
# $BB
# apples cherries
# -111 -222

最佳答案

tapply适用于向量,对于 data.frame,您可以使用 by (这是 tapply 的包装器,看一下代码):

> by(df.1[,c(3:5)], df.1$state, FUN=colSums)
df.1$state: AA
apples cherries plums
111 222 333
-------------------------------------------------------------------------------------
df.1$state: BB
apples cherries plums
-111 -222 -333

关于r - 使用 tapply 按组对多列求和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17903205/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com