我的问题标题几乎与dlply
(plyr
包)描述相匹配,但“嵌套”部分除外。
让我用一个例子来解释:
library(plyr)
res <- dlply(mtcars, c("gear", "carb"), identity)
head(res, 2)
# $`3.1`
# mpg cyl disp hp drat wt qsec vs am gear carb
# Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
# Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
# Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
#
# $`3.2`
# mpg cyl disp hp drat wt qsec vs am gear carb
# Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
# Dodge Challenger 15.5 8 318 150 2.76 3.520 16.87 0 0 3 2
# AMC Javelin 15.2 8 304 150 3.15 3.435 17.30 0 0 3 2
# Pontiac Firebird 19.2 8 400 175 3.08 3.845 17.05 0 0 3 2
如您所见,输出是一个列表,其中名称(键)是我用于分割数据的两个变量的串联,例如, "3.1"
是(gear = 3, carb = 1)
的关键。
相反,我希望我的结果是一个嵌套列表,因此可以通过两组键访问元素,每个键用于我的每个分裂变量:res[["3"][["1"]]
。
是否存在可以实现此目的的plyr
包中的某些内容?我希望答案可以推广到任意数量的分裂变量。此外,重要的是我可以应用任何函数,尽管我的示例使用identity
函数,导致仅仅分割数据。谢谢你的建议。
答案 0 :(得分:3)
我自己带来了一个解决方案,它使用了递归:
nested.dlply <- function(df, by, fun, ...) {
require(plyr)
if (length(by) == 1) {
dlply(df, by, fun, ...)
} else {
dlply(df, by[1], nested.dlply, by[-1], fun, ...)
}
}
以下是几个例子:
nested.dlply(mtcars, c("gear", "carb"), identity)
# $`3`
# $`3`$`1`
# mpg cyl disp hp drat wt qsec vs am gear carb
# Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
# Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
# Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
#
# $`3`$`2`
# mpg cyl disp hp drat wt qsec vs am gear carb
# Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
# Dodge Challenger 15.5 8 318 150 2.76 3.520 16.87 0 0 3 2
# AMC Javelin 15.2 8 304 150 3.15 3.435 17.30 0 0 3 2
# Pontiac Firebird 19.2 8 400 175 3.08 3.845 17.05 0 0 3 2
# [...]
nested.dlply(mtcars, c("gear", "carb"), head, 2)
# $`3`
# $`3`$`1`
# mpg cyl disp hp drat wt qsec vs am gear carb
# Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
# Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
#
# $`3`$`2`
# mpg cyl disp hp drat wt qsec vs am gear carb
# Hornet Sportabout 18.7 8 360 175 3.15 3.44 17.02 0 0 3 2
# Dodge Challenger 15.5 8 318 150 2.76 3.52 16.87 0 0 3 2
# [...]
我怀疑这是非常有效但它能完成这项工作。我仍然欢迎你的建议。理想情况下,我希望一些包已经实现了它。
答案 1 :(得分:2)
嵌套split
怎么样?
temp = lapply(split(mtcars, mtcars$gear), function(x) split(x, x$carb))
temp[["3"]]["1"]
# $`1`
# mpg cyl disp hp drat wt qsec vs am gear carb
# Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
# Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
# Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1