r - 在两个或多个变量上使用 Melt() 时,如何保留串联变量的两个部分? (数据.表::熔化())

标签 r data.table melt

我正在尝试使用 data.table::melt() 函数 reshape (即更长)具有连接变量的数据框。这两个变量都与年份连接。 [注意:我正在使用 data.table 开发版本 (1.14.3)]

library(data.table)

dt <-
  data.table(
    id = c(1, 2, 3),
    varA_2000 = c(2, 6, 1),
    varA_2001 = c(1, 1, 1),
    varA_2002 = c(1, 2, 3),
    varB_2000 = c(1, 0, 1),
    varB_2001 = c(1, 1, 1),
    varB_2002 = c(0, 0, 0)
  )

print(dt)
#>       id varA_2000 varA_2001 varA_2002 varB_2000 varB_2001 varB_2002
#>    <num>     <num>     <num>     <num>     <num>     <num>     <num>
#> 1:     1         2         1         1         1         1         0
#> 2:     2         6         1         2         0         1         0
#> 3:     3         1         1         3         1         1         0

如何使用melt()函数分离多个串联的列变量,同时使数据帧更长,以便得到这种格式?

desiredDT <- structure(
  list(
    id = c(1, 2, 3, 1, 2, 3, 1, 2, 3),
    year = c(
      2020,
      2020, 2020, 2021, 2021, 2021, 2022, 2022, 2022
    ),
    varA = c(
      2,
      6, 1, 1, 1, 1, 1, 2, 3
    ),
    varB = c(1, 0, 1, 1, 1, 1, 0, 0, 0)
  ),
  row.names = c(NA, -9L),
  class = c("data.table", "data.frame")
)
head(desiredDT)
#>   id year varA varB
#> 1  1 2020    2    1
#> 2  2 2020    6    0
#> 3  3 2020    1    1
#> 4  1 2021    1    1
#> 5  2 2021    1    1
#> 6  3 2021    1    1

此问题与 this 相关就这样。 2014 年,这篇原始文章似乎还没有一个纯粹的 data.table 解决方案。此外,我的日期集涉及制作长多个变量(即 varA 和 varB)。

到目前为止,我已经能够使用两种不同的方法生成我想要的格式(但都需要多个步骤)。

  • 方法1(融化,然后使用fcase重新标记变量)。
dx <- melt(dt,
  id.vars = "id", measure = patterns("^varA", "^varB"),
  value.name = c("varA", "varB"),
  variable.name = "year"
)
first_twoStepApproach <- dx[, year := fcase(
  year == "1", 2020,
  year == "2", 2021,
  year == "3", 2022
)]
head(first_twoStepApproach)
#>       id  year  varA  varB
#>    <num> <num> <num> <num>
#> 1:     1  2020     2     1
#> 2:     2  2020     6     0
#> 3:     3  2020     1     1
#> 4:     1  2021     1     1
#> 5:     2  2021     1     1
#> 6:     3  2021     1     1
  • 方法 2(融化,然后在第二步中使用 tstrsplit 拆分变量)
dx <- melt(dt, id.vars = "id", variable.name = c("variable"),
           value.name = c("value"),
           verbose = TRUE)
#> 'measure.vars' is missing. Assigning all columns other than 'id.vars' columns as 'measure.vars'.
#> Assigned 'measure.vars' are [varA_2000, varA_2001, varA_2002, varB_2000, ...].
dx[, c("variable", "year") := tstrsplit(variable, "_")]

second_twoStepApproach <- dcast(dx, id + year ~ variable, value.name = value)

head(second_twoStepApproach)
#> Key: <id, year>
#>       id   year  varA  varB
#>    <num> <char> <num> <num>
#> 1:     1   2000     2     1
#> 2:     1   2001     1     1
#> 3:     1   2002     1     0
#> 4:     2   2000     6     0
#> 5:     2   2001     1     1
#> 6:     2   2002     2     0

有没有办法只使用melt()来完成这个转换?

最佳答案

使用pivot_longer可能会更容易

library(tidyr)
library(dplyr)
pivot_longer(dt, cols = -id, names_to = c(".value", "year"), names_sep = "_")%>%
   arrange(year)

-输出

# A tibble: 9 × 4
     id year   varA  varB
  <dbl> <chr> <dbl> <dbl>
1     1 2000      2     1
2     2 2000      6     0
3     3 2000      1     1
4     1 2001      1     1
5     2 2001      1     1
6     3 2001      1     1
7     1 2002      1     0
8     2 2002      2     0
9     3 2002      3     0

或者通过data.table,使用measure.vars

library(data.table)
melt(dt, measure.vars = measure(value.name, year, sep = "_"))

-输出

      id   year  varA  varB
   <num> <char> <num> <num>
1:     1   2000     2     1
2:     2   2000     6     0
3:     3   2000     1     1
4:     1   2001     1     1
5:     2   2001     1     1
6:     3   2001     1     1
7:     1   2002     1     0
8:     2   2002     2     0
9:     3   2002     3     0

关于r - 在两个或多个变量上使用 Melt() 时,如何保留串联变量的两个部分? (数据.表::熔化()),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72956632/

相关文章:

r - 如何有效地确定每行中的变量值与R中data.table中相同变量后续行值之间的最大差异

R:没有for循环的子集和排序大数据帧

r - 在 R 中将行转换为列

R 减去基于类别的值和日期 tidyverse-way

r - 如何重命名一个复杂的公式?

r - 拆分和运行线性回归 - 使用 data.table

pandas - 堆叠、拆散、融合、旋转、转置?将多列转换为行的简单方法是什么(PySpark 或 Pandas)?)

python - PySpark Dataframe 将列融为行

r - Shiny 应用程序不反射(reflect)更新 RData 文件中的更改

r - 总结数据框中的因素