首页 文章

在R中重塑这个数据帧的最简单方法是什么? [重复]

提问于
浏览
1

这个问题在这里已有答案:

假设我有以下宽/杂乱的数据帧:

df1 <- data.frame(ID = c(1, 2), Gender = c("M","F"),
       Q1 = c(1, 5), Q2 = c(2, 6),
       Q3 = c(3, 7), Q4 = c(4, 8))

 ID Gender Q1 Q2 Q3 Q4
 1      M  1  2  3  4
 2      F  5  6  7  8

如何将其转换为此数据框:

df2 <- data.frame(ID = c(1, 1, 2, 2), Gender = c("M", "M", "F", "F"),
       V1 = c(1, 3, 5, 7), V2 = c(2, 4, 6, 8))

 ID Gender V1 V2
 1      M  1  2
 1      M  3  4
 2      F  5  6
 2      F  7  8

我知道有多个包和函数(例如,tidyr,reshape2,reshape函数)可以实现这一点 . 这是最简单的方法,如何做?非常感谢任何人都能提供的帮助 . 谢谢!

1 回答

  • 3

    您可以从 data.table 的开发版本中尝试 melt ,即 v1.9.5 . 它可以将 measure.vars 中的多个变量作为列表 . 安装devel版本的说明是here

    library(data.table)#v1.9.5+
    melt(setDT(df1), measure.vars=list(c(3,5), c(4,6)), 
      value.name=c('V1', 'V2'))[,variable:=NULL][order(ID)]
    #   ID Gender V1 V2
    #1:  1      M  1  2
    #2:  1      M  3  4
    #3:  2      F  5  6
    #4:  2      F  7  8
    

    或者使用 reshape 来自 base R

    res <- subset(reshape(df1, idvar=c('ID', 'Gender'), 
           varying=list(c(3,5), c(4,6)), direction='long'), select=-time)
    row.names(res) <- NULL
    

    更新

    如果我们需要将'df2'转换回'df1',可以使用 data.table 中的 dcast . 它可能需要多个 value.var 列 . 在继续 dcast 之前,我们需要按组('ID','Gender')创建一个序列列( N

    dcast(setDT(df2)[, N:=1:.N, list(ID, Gender)], ID+Gender~N, 
               value.var=c('V1', 'V2'))
     #   ID Gender 1_V1 2_V1 1_V2 2_V2
     #1:  1      M    1    3    2    4
     #2:  2      F    5    7    6    8
    

    或者我们使用 ave 按组创建序列,然后使用 base R 中的 reshape .

    df2 <- transform(df2, N= ave(seq_along(ID), ID, Gender, FUN=seq_along))
     reshape(df2, idvar=c('ID', 'Gender'), timevar='N', direction='wide')
     #   ID Gender V1.1 V2.1 V1.2 V2.2
     #1  1      M    1    2    3    4
     #3  2      F    5    6    7    8
    

    数据

    df1 <- data.frame(ID = c(1, 2), Gender = c("M","F"), Q1 = c(1, 5), 
           Q2 = c(2, 6), Q3 = c(3, 7), Q4 = c(4, 8))
    
    df2 <- data.frame(ID = c(1, 1, 2, 2), Gender = c("M", "M", "F", "F"),
       V1 = c(1, 3, 5, 7), V2 = c(2, 4, 6, 8))
    

相关问题