r - 将两个变量的数据从宽数据转换为长数据

标签 r melt

我有一个包含两个宽格式变量的数据集,我想将其转换为长格式。我已经看过 R 厨师的示例,但它们仅针对一个变量。

我的数据集(graph.dat)如下所示:

 PH25   PH50    PH75    PH100   P25      P50    P75    P100      r_b    c
3.96    5.94    5.94    5.94    1,694   1,736   1,329   800     0.029   7
2.86    2.86    2.86    2.86    1,665   1,792   1,639   1,335   0.027   7
3.96    5.72    5.72    5.72    1,580   1,560   1,156   663     0.023   7

我想绘制 PH(x 轴)与 P(y 轴)的关系图。因此,对于 PH25 值,对应于 P25 的值(以及 r_b 和 c 的值);所以长格式将是:

PH       P      r_b         c
3.96    1,694   0.029       7
2.86    1,665   0.027       7
3.96    1,580   0.023       7
5.94    1,736   0.029       7
2.86    1,792   0.027       7
5.72    1,560   0.023       7
5.94    1,329   0.029       7
2.86    1,639   0.027       7
5.72    1,156   0.023       7
5.94    800     0.029       7
2.86    1,335   0.027       7
5.72    663     0.023       7

我尝试“融化”它两次,但没有成功。 这是我所做的:

graph.dat1<- melt(graph.dat, id.vars=c("PH25","PH50","PH75",
                                        "PH100","r_b", "c"),
                             variable.name="P", 
                             value.name="Pval")

新数据集 (graph.dat1) 很好,因为每个“P”只有三个值(总共有 12 个观察值)。它看起来像这样:

    PH25    PH50    PH75    PH100   r_b     c    P     Pval
1   3.96    5.94    5.94    5.94    0.029   7   P25    1694
2   2.86    2.86    2.86    2.86    0.027   7   P25    1665
3   3.96    5.72    5.72    5.72    0.023   7   P25    1580
4   3.96    5.94    5.94    5.94    0.029   7   P50    1736
5   2.86    2.86    2.86    2.86    0.027   7   P50     1792
6   3.96    5.72    5.72    5.72    0.023   7   P50     1560
7   3.96    5.94    5.94    5.94    0.029   7   P75     1329
8   2.86    2.86    2.86    2.86    0.027   7   P75     1639
9   3.96    5.72    5.72    5.72    0.023   7   P75     1156
10  3.96    5.94    5.94    5.94    0.029   7   P100    800
11  2.86    2.86    2.86    2.86    0.027   7   P100    1335
12  3.96    5.72    5.72    5.72    0.023   7   P100    663

但是当我进行第二次“融化”时,它不起作用,我不知道如何解决它。这是我做的第二步:

graph.dat2<- melt (graph.dat1,id.vars=c("r_b", "c", "P", "Pval"),
                   variable.name="PdH",
                   value.name="PH")

但随后我得到了 4 倍的观测值(因此我得到了 48 个观测值,而不是 12 个观测值)。因此,我的新数据集 (graph.dat2) 如下所示:

    r_b     c   P     Pval  PdH      PH
1   0.029   7   P25   1694  PH25    3.96
2   0.027   7   P25   1665  PH25    2.86
3   0.023   7   P25   1580  PH25    3.96
4   0.029   7   P50   1736  PH25    3.96
5   0.027   7   P50   1792  PH25    2.86
6   0.023   7   P50   1560  PH25    3.96
7   0.029   7   P75   1329  PH25    3.96
8   0.027   7   P75   1639  PH25    2.86
9   0.023   7   P75   1156  PH25    3.96
10  0.029   7   P100   800  PH25    3.96
11  0.027   7   P100  1335  PH25    2.86
12  0.023   7   P100   663  PH25    3.96
13  0.029   7   P25   1694  PH50    5.94
14  0.027   7   P25   1665  PH50    2.86
15  0.023   7   P25   1580  PH50    5.72
...

最佳答案

最新版本的data.table允许melt multiple columns simultaneously .

不幸的是,两组列均以字母 P 开头。简单地指定 patterns("PH", "P") 是行不通的,因为 P 将匹配 PH 列以及 >P 列导致 24 行而不是 12 行。稍微修改一下正则表达式 patterns("PH", "P\\d") 将起作用:

library(data.table)   # CRAN version 1.10.4 used
graph.dat1 <- melt(setDT(graph.dat), measure.vars = patterns("PH", "P\\d"), 
     value.name = c("PH", "P"))
# rename factor levels of variable
graph.dat1[, variable := forcats::lvls_revalue(variable, c("25", "50", "75", "100"))][]
      r_b c variable   PH     P
 1: 0.029 7       25 3.96 1,694
 2: 0.027 7       25 2.86 1,665
 3: 0.023 7       25 3.96 1,580
 4: 0.029 7       50 5.94 1,736
 5: 0.027 7       50 2.86 1,792
 6: 0.023 7       50 5.72 1,560
 7: 0.029 7       75 5.94 1,329
 8: 0.027 7       75 2.86 1,639
 9: 0.023 7       75 5.72 1,156
10: 0.029 7      100 5.94   800
11: 0.027 7      100 2.86 1,335
12: 0.023 7      100 5.72   663

请注意,需要使用 setDT(graph.dat) 或将 graph.dat 强制为 data.table 对象data.table(graph.dat)。否则,reshape2::melt() 将被调度到无法识别 patterns() 的 data.frame 对象上。

另请注意,类似问题有一个答案 here但所需的 patterns() 却截然不同。

数据

library(data.table)
graph.dat <- fread(
"PH25   PH50    PH75    PH100   P25      P50    P75    P100      r_b    c
3.96    5.94    5.94    5.94    1,694   1,736   1,329   800     0.029   7
2.86    2.86    2.86    2.86    1,665   1,792   1,639   1,335   0.027   7
3.96    5.72    5.72    5.72    1,580   1,560   1,156   663     0.023   7",
data.table = FALSE)

关于r - 将两个变量的数据从宽数据转换为长数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44895273/

相关文章:

r - 如何将 R 中的项目列表转换为空向量?

r - 从 data.frame 转换为数字矩阵时,为什么值会发生变化?

r - 使用 R 替代具有 "dynamic"变量的 for 循环

python - 具有多个值变量的 Pandas Melt

r - melt.data.table 和 na.rm 作为 measure.vars 列表的第一个元素

使用 R 中重新出现的列名称从宽到长 reshape 数据框

r - Knit 更改图像尺寸

R 中的 read.csv 不会从 csv 文件中导入所有行

r - 如何使用 dplyr 熔化和类型转换数据框?

python - Pandas:如何(干净地)反转具有相同类别的两列?