【问题标题】:R using Reshape2 to do what reshape (stats package function) was designed forR 使用 Reshape2 来完成 reshape (统计包功能)的设计目的
【发布时间】:2014-09-02 19:28:47
【问题描述】:

我正在尝试完全按照 stats 包的 reshape 设计。我有一个广泛的数据集,其中包含var_name.date 形式的一系列变量。不幸的是,reshape 似乎无法处理中等规模的数据集,所以我尝试使用 data.table.melt 函数。

我的主要问题是根据变量的长格式变量将变量分组到单独的值列中。这可能吗,还是我需要分别做每一个然后cbind他们?

这是我所拥有的:

widetable = data.table("id"=1:5,"A.2012-10"=runif(5),"A.2012-11"=runif(5),
                       "B.2012-10"=runif(5),"B.2012-11"=runif(5))


   id  A.2012-10 A.2012-11  B.2012-10 B.2012-11
1:  1 0.82982349 0.2257782 0.46390924 0.4448248
2:  2 0.46136746 0.2184797 0.05640388 0.4772663
3:  3 0.61723234 0.3950625 0.03252784 0.4006974
4:  4 0.19963437 0.7028052 0.06811452 0.3096969
5:  5 0.09575389 0.5510507 0.76059610 0.8630222

这里是 stats 包的 reshape 嘲笑我用一行代码做我想要的但不缩放。

reshape(widetable, idvar="id", varying=colnames(widetable)[2:5],
        sep=".", direction="long")


    id  time          A          B
 1:  1 2012-10 0.82982349 0.46390924
 2:  2 2012-10 0.46136746 0.05640388
 3:  3 2012-10 0.61723234 0.03252784
 4:  4 2012-10 0.19963437 0.06811452
 5:  5 2012-10 0.09575389 0.76059610
 6:  1 2012-11 0.22577823 0.44482478
 7:  2 2012-11 0.21847969 0.47726629
 8:  3 2012-11 0.39506249 0.40069737
 9:  4 2012-11 0.70280519 0.30969695
10:  5 2012-11 0.55105075 0.86302220

【问题讨论】:

    标签: r data.table reshape2 melt


    【解决方案1】:

    这只是reshape() 更易于使用的那些时候之一。

    我能想到的使用meltdcast.data.table组合的最直接的方法如下:

    library(data.table)
    library(reshape2)
    
    longtable <- melt(widetable, id.vars = "id")
    vars <- do.call(rbind, strsplit(as.character(longtable$variable), ".", TRUE))
    dcast.data.table(longtable[, c("V1", "V2") := lapply(1:2, function(x) vars[, x])],
                     id + V2 ~ V1, value.var = "value")
    

    另一种方法是使用my "splitstackshape" package 中的merged.stack,特别是开发版本。

    # library(devtools)
    # install_github("splitstackshape", "mrdwab", ref = "devel")
    library(splitstackshape)
    
    merged.stack(widetable, id.vars = "id", var.stubs = c("A", "B"), sep = "\\.")
    #     id .time_1          A         B
    #  1:  1 2012-10 0.26550866 0.2059746
    #  2:  1 2012-11 0.89838968 0.4976992
    #  3:  2 2012-10 0.37212390 0.1765568
    #  4:  2 2012-11 0.94467527 0.7176185
    #  5:  3 2012-10 0.57285336 0.6870228
    #  6:  3 2012-11 0.66079779 0.9919061
    #  7:  4 2012-10 0.90820779 0.3841037
    #  8:  4 2012-11 0.62911404 0.3800352
    #  9:  5 2012-10 0.20168193 0.7698414
    # 10:  5 2012-11 0.06178627 0.7774452
    

    merged.stack 函数的工作方式与简单的melt 不同,因为它首先“堆叠”list 中的不同列组,然后将它们合并在一起。这允许函数:

    1. 使用列组,其中每个列组可能属于不同的类型(字符、数字等)。
    2. 使用“不平衡”列组(其中一个组可能有两个度量列,另一个可能有三个)。

    此答案基于以下示例数据:

    set.seed(1) # Please use `set.seed()` when sharing an example with random numbers
    widetable = data.table("id"=1:5,"A.2012-10"=runif(5),"A.2012-11"=runif(5),
                           "B.2012-10"=runif(5),"B.2012-11"=runif(5))
    

    另见:What reshaping problems can melt/cast not solve in a single step?

    【讨论】:

    • 感谢您的回复,并确认我想要的不能像使用 melt 一样简单地完成。我一直在尝试使用 merge.stack 来处理你的包,但我认为我必须辞职来做它。作为参考,该表有约 150k 行(ids)和 555 个变量——38 * 14 个时间段 + 一些与时间无关的其他时间段。大约 450mb,我正在使用 8GB RAM 和 8GB 虚拟内存,但是您的 merge.stackreshape 都超出了我的内存容量。
    • @user3747260,很好奇:如果您将数据加载为“data.table”,tables() 报告的大小是多少?
    猜你喜欢
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 2014-12-18
    • 2016-12-23
    • 1970-01-01
    • 2014-12-28
    • 2014-12-31
    • 1970-01-01
    相关资源
    最近更新 更多