【问题标题】:Turn wide to long dataframe with R reshape function, with three levels of duplicates [duplicate]使用 R 重塑功能将宽数据帧变为长数据帧,具有三个级别的重复项 [重复]
【发布时间】:2017-10-03 16:19:54
【问题描述】:

我一直在为 R 重塑功能而苦苦挣扎,但仍然希望始终如一地使用它,因为它是 R 核心。我偶然发现了这个问题,有像这样的宽数据框

dw <- read.table(header=T, text='
 sbj A.f1.avg A.f1.sd A.f2.avg A.f2.sd B.f1.avg B.f1.sd B.f2.avg B.f2.sd
   A       10       6       50      10       10       6       50      10  
   B       12       5       70      11       12       5       70      11  
   C       20       7       20      8        20       7       20      8   
   D       22       8       22      9        22       8       22      9   
 ')    

我希望得到这样的结果:

sbj AB  f   var res
A   A   f1  avg 10
B   A   f1  avg 12
C   A   f1  avg 20
D   A   f1  avg 22
A   A   f1  sd  6
B   A   f1  sd  5
C   A   f1  sd  7
D   A   f1  sd  8
A   A   f2  avg 50
B   A   f2  avg 70
C   A   f2  avg 20
D   A   f2  avg 22
A   A   f2  sd  10
B   A   f2  sd  11
C   A   f2  sd  8
D   A   f2  sd  9
A   B   f1  avg 10
B   B   f1  avg 12
C   B   f1  avg 20
D   B   f1  avg 22
A   B   f1  sd  6
B   B   f1  sd  5
C   B   f1  sd  7
D   B   f1  sd  8
A   B   f2  avg 50
B   B   f2  avg 70
C   B   f2  avg 20
D   B   f2  avg 22
A   B   f2  sd  10
B   B   f2  sd  11
C   B   f2  sd  8
D   B   f2  sd  9

请帮忙!

【问题讨论】:

    标签: r reshape


    【解决方案1】:

    使用reshape2...

    library(reshape2)
    dw2 <- melt(dw, id.vars="sbj", value.name="res") #melt to long format
    
    #create new variables by splitting column at dots
    dw2[, c("AB", "f", "var")] <- t(as.data.frame((strsplit(as.character(dw2$variable),"\\."))))
    
    #reorder variables
    dw2 <- dw2[,c("sbj", "AB", "f", "var", "res")]
    
    dw2
       sbj AB  f var   res
    1    A  A f1 avg    10
    2    B  A f1 avg    12
    3    C  A f1 avg    20
    4    D  A f1 avg    22
    5    A  A f1  sd     6
    6    B  A f1  sd     5
    7    C  A f1  sd     7
    8    D  A f1  sd     8
    9    A  A f2 avg    50
    10   B  A f2 avg    70
    11   C  A f2 avg    20
    12   D  A f2 avg    22
    13   A  A f2  sd    10
    14   B  A f2  sd    11
    15   C  A f2  sd     8
    16   D  A f2  sd     9
    17   A  B f1 avg    10
    18   B  B f1 avg    12
    19   C  B f1 avg    20
    20   D  B f1 avg    22
    21   A  B f1  sd     6
    22   B  B f1  sd     5
    23   C  B f1  sd     7
    24   D  B f1  sd     8
    25   A  B f2 avg    50
    26   B  B f2 avg    70
    27   C  B f2 avg    20
    28   D  B f2 avg    22
    29   A  B f2  sd    10
    30   B  B f2  sd    11
    31   C  B f2  sd     8
    32   D  B f2  sd     9
    

    【讨论】:

      【解决方案2】:

      使用dplyrtidyr

      library(dplyr)
      library(tidyr)
      
      X <- gather(dw, var, res, -sbj) %>%
          separate(var, into = c("AB", "f", "var"))
      

      结果:

      > head(X)
        sbj AB  f var res
      1   A  A f1 avg  10
      2   B  A f1 avg  12
      3   C  A f1 avg  20
      4   D  A f1 avg  22
      5   A  A f1  sd   6
      6   B  A f1  sd   5
      

      【讨论】:

      • 谢谢!所以 reshape() 不可能/更难?
      【解决方案3】:

      这是一个基本的 R 方法,它使用 stackcbind 进行初始“reshape long”,然后执行第二步将 dw 的变量名称分解为单独的列。

      # get a 3 column df
      dat <- cbind(dw[1], stack(dw[-1]))
      
      # split the variable names, reorder columns, and provide desired names
      dat <- setNames(cbind(dat[1],
                            do.call(rbind, strsplit(as.character(dat$ind), ".", fixed=TRUE)),
                            dat[2]),
                       c("sbj", "AB", "f", "var", "res"))
      

      【讨论】:

        猜你喜欢
        • 2017-07-19
        • 2021-05-01
        • 2022-07-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-15
        • 1970-01-01
        相关资源
        最近更新 更多