【问题标题】:Dcast or Reshape dataframe in RR中的Dcast或重塑数据框
【发布时间】:2023-04-06 19:15:01
【问题描述】:

我有一个这样的数据框:

originalDF <- data.frame(A1=c(1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6), 
                         A2=c(12.2, 12.2, 15.0, 34.123, 2.0, 66.0, 7.0, 7.0, 7.0, 7.0, 7.0), 
                         A3=c('T1', 'T2', 'T1', 'T1', 'T2', 'T1', 'T1', 'T1', 'T1', 'T1', 'T1'), 
                         A4=c('1234', '1234', '1234', '1234', '4321', '4321', '4321', '4321', '4321', '4321', '4321'),
                         A5=c('0245', '0245', '0500', '0500', '0600', '0600', '0600','0800','0700','0900', '0900'))

   A1     A2 A3   A4   A5
1   1 12.200 T1 1234 0245
2   1 12.200 T2 1234 0245
3   2 15.000 T1 1234 0500
4   3 34.123 T1 1234 0500
5   4  2.000 T2 4321 0600
6   5 66.000 T1 4321 0600
7   6  7.000 T1 4321 0600
8   6  7.000 T1 4321 0800
9   6  7.000 T1 4321 0700
10  6  7.000 T1 4321 0900
11  6  7.000 T1 4321 0900

我现在想重新塑造它,它最终看起来像这样:

wantedDF <- cbind.data.frame(originalDF, 
                              A3_0245=c('T1', 'T2', NA, NA, NA, NA, NA, NA, NA, NA, NA), 
                              A3_0500=c(NA, NA, 'T1', 'T1', NA, NA, NA, NA, NA, NA, NA), 
                              A3_0600=c(NA, NA, NA, NA, 'T2', 'T1', 'T1', NA, NA, NA, NA), 
                              A3_0800=c(NA, NA, NA, NA, NA, NA, NA, 'T1', NA, NA, NA), 
                              A3_0700=c(NA, NA, NA, NA, NA, NA, NA, NA, 'T1', NA, NA), 
                              A3_0900=c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 'T1', 'T1'))

   A1     A2 A3   A4   A5 A3_0245 A3_0500 A3_0600 A3_0800 A3_0700 A3_0900
1   1 12.200 T1 1234 0245      T1    <NA>    <NA>    <NA>    <NA>    <NA>
2   1 12.200 T2 1234 0245      T2    <NA>    <NA>    <NA>    <NA>    <NA>
3   2 15.000 T1 1234 0500    <NA>      T1    <NA>    <NA>    <NA>    <NA>
4   3 34.123 T1 1234 0500    <NA>      T1    <NA>    <NA>    <NA>    <NA>
5   4  2.000 T2 4321 0600    <NA>    <NA>      T2    <NA>    <NA>    <NA>
6   5 66.000 T1 4321 0600    <NA>    <NA>      T1    <NA>    <NA>    <NA>
7   6  7.000 T1 4321 0600    <NA>    <NA>      T1    <NA>    <NA>    <NA>
8   6  7.000 T1 4321 0800    <NA>    <NA>    <NA>      T1    <NA>    <NA>
9   6  7.000 T1 4321 0700    <NA>    <NA>    <NA>    <NA>      T1    <NA>
10  6  7.000 T1 4321 0900    <NA>    <NA>    <NA>    <NA>    <NA>      T1
11  6  7.000 T1 4321 0900    <NA>    <NA>    <NA>    <NA>    <NA>      T1

我怎样才能做到这一点?我已经问了一个类似的问题here,但我无法开始工作:(。 这是我已经尝试过的:

DfNames <- unique(originalDF$A5)
wantedDF[,sprintf('A3_%s',DfNames )] <- NA

(现在我需要有条件地添加到每一列)

(首选 Base R 和 data.table 解决方案!)提前致谢!

【问题讨论】:

    标签: r


    【解决方案1】:

    data.table 解决方案:

    library(data.table)
    
    dt <- as.data.table(originalDF)
    dt[, toc := paste('A3', A5, sep = '_')]
    
    res <- dcast(dt, A1 + A2 + A3 + A4 + A5 + rowid(A1) ~ toc, value.var = 'A3')[, A1_1 := NULL]
    # > res[]
    #     A1     A2 A3   A4   A5 A3_0245 A3_0500 A3_0600 A3_0700 A3_0800 A3_0900
    #  1:  1 12.200 T1 1234 0245      T1      NA      NA      NA      NA      NA
    #  2:  1 12.200 T2 1234 0245      T2      NA      NA      NA      NA      NA
    #  3:  2 15.000 T1 1234 0500      NA      T1      NA      NA      NA      NA
    #  4:  3 34.123 T1 1234 0500      NA      T1      NA      NA      NA      NA
    #  5:  4  2.000 T2 4321 0600      NA      NA      T2      NA      NA      NA
    #  6:  5 66.000 T1 4321 0600      NA      NA      T1      NA      NA      NA
    #  7:  6  7.000 T1 4321 0600      NA      NA      T1      NA      NA      NA
    #  8:  6  7.000 T1 4321 0700      NA      NA      NA      T1      NA      NA
    #  9:  6  7.000 T1 4321 0800      NA      NA      NA      NA      T1      NA
    # 10:  6  7.000 T1 4321 0900      NA      NA      NA      NA      NA      T1
    # 11:  6  7.000 T1 4321 0900      NA      NA      NA      NA      NA      T1
    

    【讨论】:

      【解决方案2】:
      #You can try this. 
      
          library(reshape2)
          originalDF <- data.frame(A1=c(1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6), 
                                   A2=c(12.2, 12.2, 15.0, 34.123, 2.0, 66.0, 7.0, 7.0, 7.0, 7.0, 7.0), 
                                   A3=c('T1', 'T2', 'T1', 'T1', 'T2', 'T1', 'T1', 'T1', 'T1', 'T1', 'T1'), 
                                   A4=c('1234', '1234', '1234', '1234', '4321', '4321', '4321', '4321', '4321', '4321', '4321'),
                                   A5=c('0245', '0245', '0500', '0500', '0600', '0600', '0600','0800','0700','0900', '0900'),stringsAsFactors = F)
          originalDF$Ind=as.numeric(row.names(originalDF))
          DF=(acast(originalDF, Ind~paste('A3_',A5), value.var="A3"))    
          originalDF=cbind(originalDF,DF)
      
      
      > originalDF
         A1     A2 A3   A4   A5 Ind A3_ 0245 A3_ 0500 A3_ 0600 A3_ 0700 A3_ 0800 A3_ 0900
      1   1 12.200 T1 1234 0245   1   T1 <NA> <NA> <NA> <NA> <NA>
      2   1 12.200 T2 1234 0245   2   T2 <NA> <NA> <NA> <NA> <NA>
      3   2 15.000 T1 1234 0500   3 <NA>   T1 <NA> <NA> <NA> <NA>
      4   3 34.123 T1 1234 0500   4 <NA>   T1 <NA> <NA> <NA> <NA>
      5   4  2.000 T2 4321 0600   5 <NA> <NA>   T2 <NA> <NA> <NA>
      6   5 66.000 T1 4321 0600   6 <NA> <NA>   T1 <NA> <NA> <NA>
      7   6  7.000 T1 4321 0600   7 <NA> <NA>   T1 <NA> <NA> <NA>
      8   6  7.000 T1 4321 0800   8 <NA> <NA> <NA> <NA>   T1 <NA>
      9   6  7.000 T1 4321 0700   9 <NA> <NA> <NA>   T1 <NA> <NA>
      10  6  7.000 T1 4321 0900  10 <NA> <NA> <NA> <NA> <NA>   T1
      11  6  7.000 T1 4321 0900  11 <NA> <NA> <NA> <NA> <NA>   T1
      

      【讨论】:

      • @mt1022 你的回答也不错~+1 给你
      【解决方案3】:

      使用data.tabledcast

      library(data.table)
      
      dat <- data.table(A1=c(1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6), 
                               A2=c(12.2, 12.2, 15.0, 34.123, 2.0, 66.0, 7.0, 7.0, 7.0, 7.0, 7.0), 
                               A3=c('T1', 'T2', 'T1', 'T1', 'T2', 'T1', 'T1', 'T1', 'T1', 'T1', 'T1'), 
                               A4=c('1234', '1234', '1234', '1234', '4321', '4321', '4321', '4321', '4321', '4321', '4321'),
                               A5=c('0245', '0245', '0500', '0500', '0600', '0600', '0600','0800','0700','0900', '0900'))
      
      dat2 <- dcast(dat, 
                    A1 + A2 + A3 + A4 + A5 ~ A5, 
                    value.var = "A3", 
                    fun = function(x) x, 
                    fill = NA)
      

      结果:

          A1     A2 A3   A4   A5 0245 0500 0600 0700 0800 0900
       1:  1 12.200 T1 1234 0245   T1   NA   NA   NA   NA   NA
       2:  1 12.200 T2 1234 0245   T2   NA   NA   NA   NA   NA
       3:  2 15.000 T1 1234 0500   NA   T1   NA   NA   NA   NA
       4:  3 34.123 T1 1234 0500   NA   T1   NA   NA   NA   NA
       5:  4  2.000 T2 4321 0600   NA   NA   T2   NA   NA   NA
       6:  5 66.000 T1 4321 0600   NA   NA   T1   NA   NA   NA
       7:  6  7.000 T1 4321 0600   NA   NA   T1   NA   NA   NA
       8:  6  7.000 T1 4321 0700   NA   NA   NA   T1   NA   NA
       9:  6  7.000 T1 4321 0800   NA   NA   NA   NA   T1   NA
      10:  6  7.000 T1 4321 0900   NA   NA   NA   NA   NA   T1
      

      您会注意到缺少第 11 行。这是因为 10 和 11 是重复的。您可以随时使用合并将它们拉回。

      merge(dat,
            dat2,
            by = c("A1", "A2", "A3", "A4", "A5"),
            all.x = TRUE)
      
          A1     A2 A3   A4   A5 0245 0500 0600 0700 0800 0900
       1:  1 12.200 T1 1234 0245   T1   NA   NA   NA   NA   NA
       2:  1 12.200 T2 1234 0245   T2   NA   NA   NA   NA   NA
       3:  2 15.000 T1 1234 0500   NA   T1   NA   NA   NA   NA
       4:  3 34.123 T1 1234 0500   NA   T1   NA   NA   NA   NA
       5:  4  2.000 T2 4321 0600   NA   NA   T2   NA   NA   NA
       6:  5 66.000 T1 4321 0600   NA   NA   T1   NA   NA   NA
       7:  6  7.000 T1 4321 0600   NA   NA   T1   NA   NA   NA
       8:  6  7.000 T1 4321 0700   NA   NA   NA   T1   NA   NA
       9:  6  7.000 T1 4321 0800   NA   NA   NA   NA   T1   NA
      10:  6  7.000 T1 4321 0900   NA   NA   NA   NA   NA   T1
      11:  6  7.000 T1 4321 0900   NA   NA   NA   NA   NA   T1
      

      您还可以轻松设置列名:

      setnames(dat2, unique(dat$A5), paste("A3", unique(dat$A5), sep = "_"))
      
          A1     A2 A3   A4   A5 A3_0245 A3_0500 A3_0600 A3_0700 A3_0800 A3_0900
       1:  1 12.200 T1 1234 0245      T1      NA      NA      NA      NA      NA
       2:  1 12.200 T2 1234 0245      T2      NA      NA      NA      NA      NA
       3:  2 15.000 T1 1234 0500      NA      T1      NA      NA      NA      NA
       4:  3 34.123 T1 1234 0500      NA      T1      NA      NA      NA      NA
       5:  4  2.000 T2 4321 0600      NA      NA      T2      NA      NA      NA
       6:  5 66.000 T1 4321 0600      NA      NA      T1      NA      NA      NA
       7:  6  7.000 T1 4321 0600      NA      NA      T1      NA      NA      NA
       8:  6  7.000 T1 4321 0700      NA      NA      NA      T1      NA      NA
       9:  6  7.000 T1 4321 0800      NA      NA      NA      NA      T1      NA
      10:  6  7.000 T1 4321 0900      NA      NA      NA      NA      NA      T1
      11:  6  7.000 T1 4321 0900      NA      NA      NA      NA      NA      T1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-10
        • 1970-01-01
        相关资源
        最近更新 更多