使用返回向量的函数与ave()函数

3
我想知道将分位数列添加到数据集中的最佳方法是什么。我考虑使用ave()函数,例如ave(iris$Sepal.Length, iris$Species, FUN=quantile) - 但在这种情况下,ave()会合并quantile()返回的值(在这种情况下,每个子集返回5个值)并将它们裁剪到iris的长度...感谢您提前的建议!
2个回答

4

这个普遍的话题在SO上有很多问题,推荐使用ave()aggregate()plyr()reshape2::castdata.table等方法,具体取决于个人偏好、可读性、紧凑性、灵活性和速度... 这里有一个简单的解决方案,使用aggregate(),似乎可以实现你想要的功能:

(aa <- aggregate(Sepal.Length~Species,data=iris,quantile))

##      Species Sepal.Length.0% Sepal.Length.25% Sepal.Length.50% Sepal.Length.75%
## 1     setosa           4.300            4.800            5.000            5.200
## 2 versicolor           4.900            5.600            5.900            6.300
## 3  virginica           4.900            6.225            6.500            6.900
##   Sepal.Length.100%
## 1             5.800
## 2             7.000
## 3             7.900

编辑: 根据评论重新阅读,这不是您想要的: 您需要摘要值在每行中被复制,而不仅仅是每组一次。

也许

merge(iris,aa,by="Species")

虽然这会得到一个有点奇怪的数据框(最后一列实际上是一个矩阵)。

这有点神奇,但是

merge(iris,with(aa,data.frame(Species,Sepal.Length)))

更好的方法是使用 tidyr,它可以更好地解析由 aggregate() 返回的奇怪数据框(名称仍然有点奇怪)。

Ben,感谢您的快速回答!我知道聚合函数,但它返回一个“汇总”表格而不是原始值,而我想保留原始表格并仅添加带有分位数的列(是的,其中会有一些冗余)。 - Vasily A
1
使用 merge 变量完美地运作(尽管最初我试图不使用它:])。但是我应该指出,recast 不正确:如果您查看前15行,您会发现从第11行开始,分位数值是从另一个子集中获取的。 因此,我将使用 merge 变量。再次感谢! - Vasily A
1
P.S. @Ben,你能给我一些提示,让我知道在哪里可以阅读更多关于 aggregate() 返回的这种“奇怪”形式的信息吗? 这不是我第一次遇到它,因此我想了解这个矩阵组成的列发生的原因以及如何总体上处理它。 我不想创建单独的问题,因为它似乎是非常基础的东西 - 我只是不知道正确的关键字来找到这个主题... - Vasily A
1
如果你能想出一个表达方式,这实际上会是一个很好的问题。我不知道它在哪里有记录,除了在 ?data.frame 中间接提到:如果将列表、数据框或矩阵传递给 'data.frame',那么就好像每个组件或列都被作为单独的参数传递(除了类别为“model.matrix”的矩阵和受“I”保护的矩阵)。 它通常不会出现在用户生成的数据框中... - Ben Bolker

3
使用 data.table 包:
library(data.table)
dt <- data.table(iris)
dt[, paste0("q", 25*(0:4)) := as.list(quantile(Sepal.Length)), by="Species"]

最后一行似乎有一个错别字(缺少括号?)- 这导致我出现了错误 Error in \[.data.frame`(dt, , `:=`(paste0("q", 25 * (0:4)), as.list(quantile(Sepal.Length))), : unused argument(s) (by = "Species")`。 - Vasily A
糟糕,是我的错:错误是由于在RStudio中查看表格引起的。感谢提供另一种解决方案! - Vasily A

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接