【问题标题】:R - reorganizing a molten data.frame with variable pairsR - 用可变对重组熔融数据帧
【发布时间】:2013-09-16 23:52:28
【问题描述】:

对不起,我的帖子标题不是特别清楚..我希望我的例子会更清楚!

如果我从数据框开始:

test.df <- data.frame(group=c(rep("a",4), rep("b",4)), 
                  var=rep(1:4,2),
                  min= runif(8),
                  q25=runif(8,1,2),
                  q75=runif(8,2,3),
                  max=runif(8,3,4))
head(test.df,2)
  group var        min      q25      q75      max
1     a   1 0.59078504 1.199138 2.119283 3.869486
2     a   2 0.06131107 1.676109 2.603068 3.739955

我知道可以用 id=c(group, var) 融化它

library(reshape2)
head(melt(test.df, id=c("group", "var")),2)
  group var variable      value
1     a   1      min 0.59078504
2     a   2      min 0.06131107

但我正在寻找的是一种通过配对 min-max 和 q25-q75 来获得两个“值”列的方法,它看起来像:

  group var variable  value1     value2  
1     a   1 min-max   0.59078504 3.869486
1     a   1 q25-q75   1.199138   2.119283
2     a   2 min-max   0.06131107 3.739955
2     a   2 q25-q75   1.676109   2.603068 

我有点卡在熔化/铸造上,无法将自己拉出来,我确定必须有一个巧妙的方法来完成这个?

编辑:这是一个只有两对变量的简化示例 - 其想法是通过最少的“手动”工作来解决更多对变量的问题。

【问题讨论】:

    标签: r dataframe reshape2


    【解决方案1】:

    另一个尝试:

    newnames <- c("value1","value2")
    data.frame(
      test.df[c("group","var")],
      variable=rep(c("min-max","q25-q75"),each=nrow(test.df)),
      rbind(
        setNames(test.df[c("min","max")],newnames),
        setNames(test.df[c("q25","q75")],newnames)
      )
    )
    

    结果:

       group var variable    value1   value2
    1      a   1  min-max 0.6939545 3.479807
    2      a   2  min-max 0.5646825 3.564637
    3      a   3  min-max 0.3509824 3.928308
    4      a   4  min-max 0.4217888 3.376821
    5      b   1  min-max 0.6493916 3.933157
    6      b   2  min-max 0.3978330 3.129940
    7      b   3  min-max 0.4407376 3.707715
    8      b   4  min-max 0.1651875 3.798546
    9      a   1  q25-q75 1.3531055 2.242076
    10     a   2  q25-q75 1.1811900 2.240188
    11     a   3  q25-q75 1.3043822 2.695175
    12     a   4  q25-q75 1.3315480 2.542576
    13     b   1  q25-q75 1.2397527 2.107442
    14     b   2  q25-q75 1.1973467 2.545511
    15     b   3  q25-q75 1.9193746 2.502551
    16     b   4  q25-q75 1.0425474 2.225601
    

    【讨论】:

    • @Arun - 唯一的症结是rbind 不喜欢不匹配的名字。如果可以解决,它可能会更短。
    • @maja,请注意rbindlist,因为它还没有完善,并且会与因素和不匹配的列一起使用。
    • 感谢 Ricardo 的提醒,我会仔细检查!
    【解决方案2】:

    有几种方法。例如,多次熔化、dcast、重铸等。 以下方法使用data.table

    require(data.table)
    test.dt <- data.table(rbind(test.df, test.df))
    
    ind <- 1:nrow(test.df)
    test.dt[, c("variable", "value1", "value2") :=
              list(rep(c("min-max", "q25-q75"), each=nrow(test.df)),
                   c(min[ind], q25[ind]),
                   c(max[ind], q75[ind])
                   )]
    
    ## drop the columns you don't need
    test.dt[, c("min", "max", "q25", "q75") := NULL]
    
    ## if you'd like to order it, you can use `order` or `setkey`
    ##   the latter is quicker, but changes the DT
    ##   the former is slower but the DT's order is preserved.
    test.dt[order(group, var)]
    # or
    setkey(test.dt, group, var)
    

    结果

    test.dt
    
        group var variable     value1   value2
     1:     a   1  min-max 0.63256600 3.514519
     2:     a   1  q25-q75 1.66013227 2.543394
     3:     a   2  min-max 0.53387108 3.029701
     4:     a   2  q25-q75 1.71870889 2.620395
     5:     a   3  min-max 0.41179300 3.210039
     6:     a   3  q25-q75 1.28926891 2.539023
     7:     a   4  min-max 0.58886768 3.419263
     8:     a   4  q25-q75 1.95738512 2.368881
     9:     b   1  min-max 0.06941305 3.047981
    10:     b   1  q25-q75 1.03638939 2.341807
    11:     b   2  min-max 0.64073458 3.774208
    12:     b   2  q25-q75 1.04405064 2.164377
    13:     b   3  min-max 0.57886703 3.703984
    14:     b   3  q25-q75 1.95881989 2.039100
    15:     b   4  min-max 0.25317366 3.870050
    16:     b   4  q25-q75 1.53970571 2.093513
    

    【讨论】:

    • 嘿阿伦。 cmets 是对特定内容的回应还是只是添加有用的注释?
    • 啊,明白了。是的,我也选择了setkey,但是当我只是输出视觉检查并且不想修改DT时,我使用order。为了清楚起见,我在答案中添加了注释
    【解决方案3】:

    来自data.table v1.9.5+melt 可以处理熔解到多个列。我们可以这样做:

    require(data.table) # v1.9.5+
    ans = melt(setDT(test.df), id=1:2, measure=list(c(3:4), c(6:5)))
    setattr(ans$variable, 'levels', c("min-max", "q25-q75"))
    #     group var variable     value1   value2
    #  1:     a   1  min-max 0.10099765 3.462315
    #  2:     a   2  min-max 0.08818443 3.051679
    #  3:     a   3  min-max 0.53342060 3.737234
    #  4:     a   4  min-max 0.07875220 3.560566
    #  5:     b   1  min-max 0.25263233 3.137646
    #  6:     b   2  min-max 0.10126603 3.451190
    #  7:     b   3  min-max 0.18560800 3.819189
    #  8:     b   4  min-max 0.65526231 3.721172
    #  9:     a   1  q25-q75 1.79852967 2.542847
    # 10:     a   2  q25-q75 1.41175623 2.560623
    # 11:     a   3  q25-q75 1.01159079 2.931624
    # 12:     a   4  q25-q75 1.60892118 2.392346
    # 13:     b   1  q25-q75 1.06122928 2.229654
    # 14:     b   2  q25-q75 1.13817060 2.751216
    # 15:     b   3  q25-q75 1.26490475 2.400336
    # 16:     b   4  q25-q75 1.65309127 2.213093
    

    您可以按照here的说明进行安装。

    【讨论】:

      【解决方案4】:

      一个(笨拙的!)解决方案:

      df2 <- melt(test.df, id=c("group", "var"))
      
      df3 <- within(df2, v <- substr(variable, 1, 1))
      
      minq25 <- df3$variable %in% c("min","q25")
      
      maxq75 <- !minq25
      
      df4 <- merge(df3[minq25,], df3[maxq75,], by=c("group","var","v"))
      
      df5 <- within(df4, variable <- paste(variable.x, variable.y, sep="-"))
      
      df5[,c("group","var","variable","value.x","value.y")]
      

      结果:

         group var variable    value.x  value.y
      1      a   1  min-max 0.05265472 3.879102
      2      a   1  q25-q75 1.38637281 2.083420
      3      a   2  min-max 0.04639894 3.656561
      4      a   2  q25-q75 1.38182351 2.652118
      5      a   3  min-max 0.49758025 3.227566
      6      a   3  q25-q75 1.07336356 2.193336
      7      a   4  min-max 0.08901318 3.018771
      8      a   4  q25-q75 1.11195873 2.754820
      9      b   1  min-max 0.49791501 3.494425
      10     b   1  q25-q75 1.17453226 2.221016
      11     b   2  min-max 0.66731388 3.942841
      12     b   2  q25-q75 1.71656969 2.317466
      13     b   3  min-max 0.88250686 3.258755
      14     b   3  q25-q75 1.93997804 2.191714
      15     b   4  min-max 0.32003321 3.060668
      16     b   4  q25-q75 1.05766626 2.757572
      

      【讨论】:

      • 是的,只有在现实生活中我有大约十对分位数 - 而不仅仅是我在示例中给出的两个。我应该提到这可能..
      • @maja,当然,不可能。阅读常见问题解答。
      • 对不起,我的错,我只是把“可重现的例子”自动表示“简化的例子”,然后我可以扩大规模。我以后会更加小心的,谢谢!
      猜你喜欢
      • 2016-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多