从长转换为宽,但将列标题分组

Convert from long to wide but group the column headings

我有一个 data.frame 的长格式。我想重塑为宽,但我关心列的顺序。

这是一个玩具示例。实际上,我会有更多的组(grp)。

# Minimum working example

mwe <- "grp mean sd label

1  C90   90 19 Heart_rate
2  D20   86 18 Heart_rate
3  H09   80 16 Heart_rate
9  Z89   89 18 Heart_rate"

# Read in the text data

dd <- read.table(text=mwe, header=TRUE)

我尝试了 解决方案但没有成功。

dcast(setDT(dd), label~grp, value.var=list("mean", "sd"), sep="_" )

    label mean_C90 mean_D20 mean_H09 mean_Z89 sd_C90 sd_D20 sd_H09 sd_Z89
1: Heart_rate       90       86       80       89     19     18     16     18

我想要的是 label 之后的列按 grp 然后按 meansd 排序...像这样

    label mean_C90 sd_C90 mean_D20 sd_D20 mean_H09 sd_H09 mean_Z89 sd_Z89

我卡住了!

解决此问题的一种快速方法是使用 setcolorder:

重新排列列
setcolorder(temp, c("label", paste(c("mean","sd"), 
             rep(unique(gsub("^(mean|sd)_", "", names(temp)[-1])), each=2), sep="_")))

这有点紧凑,所以这里是片段:

  • gsub("^(mean|sd)_", "", names(temp)[-1]) 打印出删除了 "mean_" 和 "sd_" 的变量名称("label" 除外)。此结果包含在 unique 中以删除重复名称。
  • 上面的结果通过 each=2 参数被提供给 rep,以便重复两次。
  • 这些重复的值被粘贴到 "mean_" 和 "sd_" 以构建所需的列顺序。
  • "label" 被连接到这个字符串向量的前面。

setcolorder 的一个好处是它通过引用更改数据,因此它不涉及对 data.table 的任何复制(即,它非常快)。

你需要先融化dd,这样meansd的值在同一列:

dcast(melt(dd), label ~ grp + variable)
#       label C90_mean C90_sd D20_mean D20_sd H09_mean H09_sd Z89_mean Z89_sd
#1 Heart_rate       90     19       86     18       80     16       89     18