dcast中的value.var可以是列表还是具有多个值变量?

Ale*_*exR 31 r reshape reshape2 data.table

在帮助文件中dcast.data.table,有一条说明已实现新功能的说明:"dcast.data.table允许value.var列为类型列表"

我认为这意味着一个列表中可以有多个值变量,即采用以下格式:

dcast.data.table(dt, x1~x2, value.var=list('var1','var2','var3'))
Run Code Online (Sandbox Code Playgroud)

但是我们得到一个错误: 'value.var' must be a character vector of length 1.

是否有这样的功能,如果没有,那么其他单线替代品会是什么?

编辑:回复以下评论

在某些情况下,您需要将多个变量视为value.var.想象一下,例如x2由3个不同的周组成,你有2个值变量,如盐和糖的消耗,你想在不同的周内投射这些变量.当然,你可以将2个值变量"融化"成一个列,但为什么要使用两个函数做什么,当你可以在一个函数中这样reshape做时呢?

(注意:我也注意到reshape不能将多个变量视为时间变量dcast.)

所以我的观点是,我不明白为什么这些函数不允许灵活地在其中包含多个变量,value.var或者time.var就像我们允许的多个变量一样id.var.

Aru*_*run 38

从data.table的v1.9.6开始,我们可以value.var同时转换多个列(并且还使用多个聚合函数fun.aggregate).请参阅使用data.tables插图?dcast高效重塑以获取更多信息.

以下是我们可以使用的方法dcast:

dcast(setDT(mydf), x1 ~ x2, value.var=c("salt", "sugar"))
#    x1 salt_1 salt_2 salt_3 sugar_1 sugar_2 sugar_3
# 1:  1      3      4      6       1       2       2
# 2:  2     10      3      9       5       3       6
# 3:  3     10      7      7       4       6       7
Run Code Online (Sandbox Code Playgroud)


A5C*_*2T1 11

更新

显然,修复更容易 ......


从技术上讲,你的声明"显然没有这样的功能"并不完全正确.功能中有这样的recast功能(隐藏了熔化和铸造过程),但似乎Hadley忘记完成功能或其他功能:该功能返回list操作的相关部分.

这是一个最小的例子......

一些样本数据:

set.seed(1)
mydf <- data.frame(x1 = rep(1:3, each = 3),
                   x2 = rep(1:3, 3),
                   salt = sample(10, 9, TRUE),
                   sugar = sample(7, 9, TRUE))

mydf
#   x1 x2 salt sugar
# 1  1  1    3     1
# 2  1  2    4     2
# 3  1  3    6     2
# 4  2  1   10     5
# 5  2  2    3     3
# 6  2  3    9     6
# 7  3  1   10     4
# 8  3  2    7     6
# 9  3  3    7     7
Run Code Online (Sandbox Code Playgroud)

你似乎想要达到的效果:

reshape(mydf, idvar='x1', timevar='x2', direction='wide')
#   x1 salt.1 sugar.1 salt.2 sugar.2 salt.3 sugar.3
# 1  1      3       1      4       2      6       2
# 4  2     10       5      3       3      9       6
# 7  3     10       4      7       6      7       7
Run Code Online (Sandbox Code Playgroud)

recast在行动.(请注意,这些值都是我们所期望的维度.)

library(reshape2)
out <- recast(mydf, x1 ~ x2 + variable, measure.var = c("salt", "sugar"))
### recast(mydf, x1 ~ x2 + variable, id.var = c("x1", "x2"))
out
# $data
#      [,1] [,2] [,3] [,4] [,5] [,6]
# [1,]    3    1    4    2    6    2
# [2,]   10    5    3    3    9    6
# [3,]   10    4    7    6    7    7
# 
# $labels
# $labels[[1]]
#   x1
# 1  1
# 2  2
# 3  3
# 
# $labels[[2]]
#   x2 variable
# 1  1     salt
# 2  1    sugar
# 3  2     salt
# 4  2    sugar
# 5  3     salt
# 6  3    sugar
Run Code Online (Sandbox Code Playgroud)

老实说,我不确定这是一个不完整的函数,还是它是另一个函数的辅助函数.

所有信息都可以将数据重新组合在一起,从而可以轻松编写如下函数:

recast2 <- function(...) {
  inList <- recast(...)
  setNames(cbind(inList[[2]][[1]], inList[[1]]),
           c(names(inList[[2]][[1]]), 
             do.call(paste, c(rev(inList[[2]][[2]]), sep = "_"))))
}
recast2(mydf, x1 ~ x2 + variable, measure.var = c("salt", "sugar"))
#   x1 salt_1 sugar_1 salt_2 sugar_2 salt_3 sugar_3
# 1  1      3       1      4       2      6       2
# 2  2     10       5      3       3      9       6
# 3  3     10       4      7       6      7       7
Run Code Online (Sandbox Code Playgroud)

同样,该recast2方法的一个可能的优点是能够在同一步骤中聚合和重塑.


Pau*_*eux 9

使用mydf来自A5C1D2H2I1M1N2O1R2T1的样本数据框的答案.

使用2016年12月编辑 tidyr

Reshape2已被tidyr包替换.

library(tidyr)
mydf  %>% 
    gather(variable, value, -x1, -x2)  %>% 
    unite(x2_variable, x2, variable)  %>% 
    spread(x2_variable, value)

#   x1 1_salt 1_sugar 2_salt 2_sugar 3_salt 3_sugar
# 1  1      3       1      4       2      6       2
# 2  2     10       5      3       3      9       6
# 3  3     10       4      7       6      7       7
Run Code Online (Sandbox Code Playgroud)

基于的原始答案 reshape2

@AlexR补充了他的问题:

当然,你可以将2个值变量"融化"成一个列,

对于那些来到这里寻找基于reshape2的答案的人来说,这里是如何融合数据然后根据"变量"使用dcast..

dt2 <- melt(mydf, id = c("x1", "x2")) 
Run Code Online (Sandbox Code Playgroud)

变量列现在将包含'var1','var2','var3'.你可以达到预期的效果

dt3 <- dcast(dt2, x1 ~ x2 + variable, value.var="value")
dt3
#   x1 1_salt 1_sugar 2_salt 2_sugar 3_salt 3_sugar
# 1  1      3       1      4       2      6       2
# 2  2     10       5      3       3      9       6
# 3  3     10       4      7       6      7       7
Run Code Online (Sandbox Code Playgroud)

value.var在此函数调用中是可选的,因为dcast会自动猜测它.