【问题标题】:R: How to dcast a subset of 'variable' to a separate column in data.table?R:如何将“变量”的子集转换为 data.table 中的单独列?
【发布时间】:2015-02-27 16:00:57
【问题描述】:

我在 data table 中有一个大数据集,我正在尝试对其进行转换。原始数据集是一个交叉表,column_names 中有 1 到 2 级信息。所以我想我需要把所有东西都写下来melt,提取相关信息,然后将各个列重新投射回去。

这是我遇到障碍的地方。

下面是一个简化的模拟数据,显示了我正在尝试做的事情:

从:

   ID1 ID2 X.Measure1 X.Measure2  Y.Measure1  Y.Measure2
1:   1   1 -0.6264538  0.4874291 -0.62124058  0.82122120
2:   2   2  0.1836433  0.7383247 -2.21469989  0.59390132
3:   3   1 -0.8356286  0.5757814  1.12493092  0.91897737
4:   1   2  1.5952808 -0.3053884 -0.04493361  0.78213630
5:   2   1  0.3295078  1.5117812 -0.01619026  0.07456498
6:   3   2 -0.8204684  0.3898432  0.94383621 -1.98935170

执行 2 个中间步骤: (i) 将整数“1”和“2”提取到新列“n”中; (ii) 将“变量”重命名为“Y.Measure”(如下左图所示)。

最终的表格由casting得到如下图右边的绿色数字:

示例代码:

library( data.table )
library( reshape2 )
library( stringr )

set.seed(1)
DT <- data.table( ID1 = rep( c(1:3),2 ), ID2 = rep( c(1:2),3 ), 
                  X.Measure1 = rnorm(6),  X.Measure2 = rnorm(6),
                  Y.Measure1 = rnorm(6),  Y.Measure2 = rnorm(6)
                  )

Long_DT <- melt( DT, id = c( "ID1", "ID2" ) )
Long_DT[ , n := substr( Long_DT$variable, 10, 10 ) ]

Long_DT[ str_detect( Long_DT$variable, "Y.Measure." ), variable := "Y.Measure"  ]

问题:

但是当我尝试 dcastsubset 参数时,我得到了错误的结果:

> dcast.data.table ( Long_DT, ID1+ID2 ~ variable, subset = (variable=="Y.Measure") )

Aggregate function missing, defaulting to 'length'
   ID1 ID2 Y.Measure
1:   1   1         2
2:   1   2         2
3:   2   1         2
4:   2   2         2
5:   3   1         2
6:   3   2         2

我尝试在谷歌上搜索解决方案,但无济于事。我想知道我的 dcast 函数是否错误,或者我的方法一开始就错误(即有一种更简单的方法可以实现我想要的)。

任何帮助将不胜感激!感谢阅读!


更新:

我在上面的 dcast 函数中发现了错误 - LHS 上应该有“n”:

dcast.data.table ( Long_DT, ID1+ID2+n ~ variable, subset = .(variable=="Y.Measure") )

结果是:

> dcast.data.table ( Long_DT, ID1+ID2+n ~ variable, subset = .(variable=="Y.Measure") )
    ID1 ID2 n   Y.Measure
 1:   1   1 1 -0.62124058
 2:   1   1 2  0.82122120
 3:   1   2 1 -0.04493361
 4:   1   2 2  0.78213630
 5:   2   1 1 -0.01619026
 6:   2   1 2  0.07456498
 7:   2   2 1 -2.21469989
 8:   2   2 2  0.59390132
 9:   3   1 1  1.12493092
10:   3   1 2  0.91897737
11:   3   2 1  0.94383621
12:   3   2 2 -1.98935170
> 

不幸的是,XMeasure1 和 XMeasure2 也与 subset 一起消失了,所以这对我的整体事业没有帮助。

【问题讨论】:

  • 试试dcast.data.table(Long_DT[, N:=1:.N, variable], ID1+ID2+N~variable, subset = (variable=="Y.Measure") )
  • 如果你需要excel图中的结果,为什么不只是子集而不是dcast
  • 嗨@akrun,我试过你的代码,但结果似乎错误。为响应您对子集的建议,dcast 是重新格式化数据以导入另一个分析软件的多步骤过程的一部分。你看,原始数据集是一个交叉表,column_names 中有 1 到 2 级信息。所以我想我需要把melt 一切都记下来,提取相关信息,然后将各个列重新投射回去。我想我也应该提到我对数据操作缺乏经验,所以我愿意接受建议。
  • 我的意思是在melt 步骤之后。您应该指定错误的部分。我在看你的excel图。 dcast 结果似乎和那个一样。
  • 我尝试使用您的dcast 代替我原来的 dcast,将结果作为答案放在下面。

标签: r casting data.table subset reshape2


【解决方案1】:

以下是我修改后的代码,加上 akrun 建议的 dcast 代码:

library( data.table )
library( reshape2 )
library( stringr )

set.seed(1)
DT <- data.table( ID1 = rep( c(1:3),2 ), ID2 = rep( c(1:2),3 ), 
                  X.Measure1 = rnorm(6),  X.Measure2 = rnorm(6),
                  Y.Measure1 = rnorm(6),  Y.Measure2 = rnorm(6)
                  )

Long_DT <- melt( DT, id = c( "ID1", "ID2" ) )
Long_DT[ , n := substr( Long_DT$variable, 10, 10 ) ]

Long_DT[ str_detect( Long_DT$variable, "Y.Measure." ), variable := "Y.Measure"  ]
dcast.data.table(Long_DT[, N:=1:.N, variable], ID1+ID2+N~variable, subset = (variable=="Y.Measure") )

结果:

    ID1 ID2  N   Y.Measure
 1:   1   1  1 -0.62124058
 2:   1   1  7  0.82122120
 3:   1   2  4 -0.04493361
 4:   1   2 10  0.78213630
 5:   2   1  5 -0.01619026
 6:   2   1 11  0.07456498
 7:   2   2  2 -2.21469989
 8:   2   2  8  0.59390132
 9:   3   1  3  1.12493092
10:   3   1  9  0.91897737
11:   3   2  6  0.94383621
12:   3   2 12 -1.98935170

【讨论】:

  • 试一试dcast.data.table(Long_DT[, N:=1:.N, variable], ID1+ID2+N~variable, subset = (variable=="Y.Measure") )[order(N)]
  • @akrun,'N' 列未显示正确的值(请参阅我的原始帖子),无论排序如何。
  • N 用于另一个分组。你可以新建一个Ndcast.data.table(Long_DT[, N:=1:.N, variable], ID1+ID2+N~variable, subset = (variable=="Y.Measure") )[order(N)][,N:=1:.N ,.(ID1, ID2)][]
【解决方案2】:

我不确定这是否是你所期望的,但我刚刚向melt.data.table 推送了一个新功能,现在它允许融合到多个列中..

您可以通过关注these instructions 安装开发版。然后你可以这样做:

require(data.table) ## v1.9.5
melt(DT, id=1:2, measure=list(3:4, 5:6), 
       value.name = c("X.measure", "Y.measure"))

默认情况下,variable 列填充有数字。如果不希望这样做,只需相应地更改变量列的级别即可。

HTH

【讨论】:

  • 谢谢@Arun,你的新功能再及时不过了!我正在阅读 Hadley Wickham 的优秀文章“整理数据”,并认为我整理数据集的方法一开始可能是错误的。直到今天,才意识到数据清理会如此复杂。而且我怀疑您的新功能可能只是解决方案 - 让我处理它并报告=)
  • 嗨 @Arun,我从 Github 下载了最新的 1.9.5 data.table 包并运行了你的新 melt 函数。恐怕我收到以下错误消息:Error in melt.data.table(DT, id = 1:2, measure = list(3:4, 5:6), value.name = c("X.measure", : Argument 'value.name' must be a character vector of length 1。实在想不通哪里出了问题。我在 Windows 8.1 上运行 R 3.1.2(64 位版本)。
  • @NoviceProg,你确定你运行的是 1.9.5 吗?你的sessionInfo() 输出告诉你什么?
  • 阿伦,我确定它是 1.9.5。为了确保包是 Github 上的最新包,我删除了旧包并再次下载。 sessionInfo() 说:&gt; sessionInfo() R version 3.1.2 (2014-10-31) Platform: x86_64-w64-mingw32/x64 (64-bit) attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] data.table_1.9.5 devtools_1.7.0 stringr_0.6.2 reshape2_1.4.1 loaded via a namespace (and not attached): [1] bitops_1.0-6 chron_2.3-45 httr_0.6.1 plyr_1.8.1 Rcpp_0.11.3 [6] RCurl_1.95-4.5 tools_3.1.2 &gt;
  • 我明白了,@Arun,也许当更多用户使用新功能时,可能会出现一种模式。同时,我使用了一种不同的方法来整理我的数据——将交叉表数据集拆分为 2 个不同的 DT,分别进行必要的转换,然后使用 X[Y] 连接 DT。这完全避免了原始的“dcast-a-subset-issue”。无论如何,非常感谢您提供这种“多色谱柱熔体”解决方案。
猜你喜欢
  • 1970-01-01
  • 2021-10-26
  • 2013-09-02
  • 1970-01-01
  • 2013-12-26
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多