在data.table中按组转置矢量

C8H*_*4O2 6 r data.table

什么是惯用的data.table方法来生成data.table,其中包含由函数返回的向量元素的单独列,由group计算?

考虑data.table:

library(data.table)
data(iris)
setDT(iris)
Run Code Online (Sandbox Code Playgroud)

如果函数是range(),我希望输出类似于:

iris[, .(min_petal_width = min(Petal.Width), 
         max_petal_width = max(Petal.Width)
         ), keyby = Species] # produces desired output
Run Code Online (Sandbox Code Playgroud)

但使用该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")
Run Code Online (Sandbox Code Playgroud)

我希望有一个更简单的表达方式,如下所示:

iris[, (c("min_petal_width","max_petal_width")) = range(Petal.Width), 
      keyby = Species] # doesn't work
Run Code Online (Sandbox Code Playgroud)

Aru*_*run 6

你也可以这样做:

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
Run Code Online (Sandbox Code Playgroud)


tal*_*lat 5

你的方法非常接近.请记住,您需要将一个列表提供给data.table,它会很乐意接受它.因此,您可以使用:

iris[, c("min_petal_width","max_petal_width") := as.list(range(Petal.Width)), 
     by = Species]
Run Code Online (Sandbox Code Playgroud)

我误解了这个问题..因为你想要聚合结果而不是添加新列,你可以使用

cols <- c("min_petal_width", "max_petal_width")
iris[, setNames(as.list(range(Petal.Width)), cols), keyby = Species] 
Run Code Online (Sandbox Code Playgroud)

但我确信还有其他一些data.table方法.

  • 这不会返回新的data.table,但会修改iris data.table就地添加两列 (2认同)