data.table
问题描述:
组内转置的向量什么是生成一个data.table单独的列的函数返回的元素,由组计算的data.table方法?data.table
考虑data.table:
library(data.table)
data(iris)
setDT(iris)
如果函数range()
,我想类似的输出:
iris[, .(min_petal_width = min(Petal.Width),
max_petal_width = max(Petal.Width)
), keyby = Species] # produces desired output
但使用range()
功能。
我可以使用dcast
,但它的丑陋:
dcast(
iris[, .(petal_width = range(Petal.Width),
value = c("min_petal_width", "max_petal_width")),
keyby = Species],
Species ~ value, value.var = "petal_width")
我希望有一个更简单的表达,沿着线:
iris[, (c("min_petal_width","max_petal_width")) = range(Petal.Width),
keyby = Species] # doesn't work
答
你的做法是非常接近的。请记住,您需要将一个列表提供给data.table,并且会很乐意接受它。因此,你可以使用:
iris[, c("min_petal_width","max_petal_width") := as.list(range(Petal.Width)),
by = Species]
我误解了问题。既然要汇总的结果,而不是增加新的栏目,你可以使用
cols <- c("min_petal_width", "max_petal_width")
iris[, setNames(as.list(range(Petal.Width)), cols), keyby = Species]
但我敢肯定有一个还有其他一些data.table方法。
答
你也可以这样做:
dt[, lapply(list(min=min, max=max), function(f) f(Petal.Width)), by=Species]
# Species min max
# 1: setosa 0.1 0.6
# 2: versicolor 1.0 1.8
# 3: virginica 1.4 2.5
答
如果可读性和简洁是对你真的很重要,我会定义一个自定义的功能或二进制运算符,然后您可以轻松地在data.table子表达式中使用,例如:
# custom function
.nm <- function(v,vnames){
`names<-`(as.list(v),vnames)
}
# custom binary operator
`%=%` <- function(vnames,v){
`names<-`(as.list(v),vnames)
}
# using custom function
iris[, .nm(range(Petal.Width),c("min_petal_width", "max_petal_width")), keyby = Species]
# using custom binary operator
iris[, c("min_petal_width", "max_petal_width") %=% range(Petal.Width), keyby = Species]
这并不返回一个新的data.table,但它会修改虹膜就地data.table增加两列,它 – digEmAll
@digEmAll,哦,你是对的,当然。 –