使用列名信息在R中将宽数据帧重新整形为长格式

时间:2013-08-15 15:52:47

标签: r dataframe reshape reshape2 melt

我很难将复杂的数据库输出从宽格式转换为长格式。它有几百行和~1,000列。 它看起来像这样:

wide df and melt result

问题是df1_long的变量或df1_wide的列包含我想要选择的信息。所以我宁愿想要这样的东西:

ID       part   task    subgroup    type    result
Ind_A       a     12          aa       2    yes
Ind_A       a     12          bb       2    yes
Ind_A       b     12          aa       3    opt_1
Ind_A       b     13          aa       4    100
Ind_B       a     12          aa       2    no
Ind_B       a     12          bb       2    yes
Ind_B       b     12          aa       3    opt_2
Ind_B       b     13          aa       4    50
Ind_C       a     12          aa       2    no
Ind_C       a     12          bb       2    no
Ind_C       b     12          aa       3    opt_1
Ind_C       b     13          aa       4    200

我不介意将数值/结果转换为字符。

使用stack()或reshape()函数有没有简单的方法来实现它? 或者我是否必须编写一个函数,在列名上执行某些strsplits命令以提取相关信息,然后将它们存储在单独的新列中。

长格式肯定会更容易使用并向数据集提问。使用那些神秘的列名称为> 1000列编码的东西对我来说就像是一场噩梦。

1 个答案:

答案 0 :(得分:4)

好的。我放弃了。

这是您的数据:

df1_wide <- data.frame(v1 = c("Ind_A", "Ind_B", "Ind_C"), 
                       v2 = c("Y", "N", "N"), v3 = c("Y", "Y", "N"), 
                       v4 = c("op1_1", "opt_2", "opt_1"), 
                       v5 = c(100, 50, 200))
rownames(df1_wide) <- letters[1:3]
colnames(df1_wide) <- c("ID", "a_t12_aa (Type # 2)", "a_t12_bb (Type # 2)", 
                        "b_t12_aa (Type # 3)", "b_t13_aa (Type # 4)")
df1_wide
#      ID a_t12_aa (Type # 2) a_t12_bb (Type # 2) b_t12_aa (Type # 3) b_t13_aa (Type # 4)
# a Ind_A                   Y                   Y               op1_1                 100
# b Ind_B                   N                   Y               opt_2                  50
# c Ind_C                   N                   N               opt_1                 200

这是你到目前为止所做的:

df1_long <- melt(df1_wide, id.vars="ID")

这听起来像是你想要的:

cbind(df1_long["ID"],
      colsplit(gsub("\\s|\\(Type|\\)|#", " ", df1_long$variable), 
               pattern="_|\\s+", 
               names = c("part", "task", "subgroup", "type")),
      df1_long["value"])
#       ID part task subgroup type value
# 1  Ind_A    a  t12       aa    2     Y
# 2  Ind_B    a  t12       aa    2     N
# 3  Ind_C    a  t12       aa    2     N
# 4  Ind_A    a  t12       bb    2     Y
# 5  Ind_B    a  t12       bb    2     Y
# 6  Ind_C    a  t12       bb    2     N
# 7  Ind_A    b  t12       aa    3 op1_1
# 8  Ind_B    b  t12       aa    3 opt_2
# 9  Ind_C    b  t12       aa    3 opt_1
# 10 Ind_A    b  t13       aa    4   100
# 11 Ind_B    b  t13       aa    4    50
# 12 Ind_C    b  t13       aa    4   200

我无法保证我与gsub一起使用的正则表达式将与您的实际数据一起使用,但希望这足以指出您正确的方向。

将来请注意,共享数据的屏幕截图非常无用。请像我在这个问题中一样分享数据,以便其他人可以轻松复制和粘贴,以便开始尝试帮助您。


您可能需要考虑将来的变量重命名为a_t12_aa_2,在这种情况下,colsplit步骤只是colsplit(variable, "_", c("part", "task", "subgroup", "type"))