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方法的一个可能的优点是能够在同一步骤中聚合和重塑.
使用mydf来自A5C1D2H2I1M1N2O1R2T1的样本数据框的答案.
tidyrReshape2已被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会自动猜测它.