【问题标题】:R function for collapsing multiple ranges of different columns from wide to long format?R函数用于折叠从宽格式到长格式的不同列的多个范围?
【发布时间】:2021-04-15 21:08:37
【问题描述】:

我有一个数据集,每行包含多个不同范围的列(每行对应一个人),如下所示。不同列类型的每个实例都有 3 个级别(0,1 和 2)。

id  col1_0 col1_1 col1_2  col2_0  col2_1 col2_2  col3_0 col3_1 col3_2
1       0      1      3       2       2      3       3      4      5
2       1      1      2       2       4      7       4      5      5
.
.
etc. 

对于每个 id,我需要将所有 col1 折叠到一列中,将所有 col2 折叠到另一列中,并将所有 col3 折叠到另一列中。如下。

id  x  col1 col2 col4
1   0     0    2    3       
1   1     1    2    4
1   2     3    3    5
2   0     1    2    4
2   1     1    4    5
2   2     1    7    5
.
.
etc.

此外,我还需要为每个 id 创建一个值为 0,1 和 2 的 x 列。但是,我只设法用下面的代码折叠第一列范围 (col1)。

library(tidyverse)

longer_data <- dataframe %>%
  group_by(id) %>%
  pivot_longer(col1_0:col1_2, names_to = "x1", values_to = "col1")

x1 在这里使用原始列名创建一个列。所以我会创建一个额外的 x 列,它只保留原始列名的最后一个数字。

有没有办法做到这一点?非常感谢!

【问题讨论】:

    标签: r tidyverse reshape


    【解决方案1】:

    我们不需要任何group_by。通过在names_to 中指定names_sep.value 可以直接使用pivot_longer 完成。注意.valuex 的顺序。这意味着该列的值应该在 _ 之前进入每个前缀,并且带有后缀存根的新列进入'x'

    library(dplyr)
    library(tidyr)
    df1 %>%
       pivot_longer(cols = -id, names_to = c('.value', 'x'), names_sep = "_")
    

    -输出

    # A tibble: 6 x 5
    #     id x      col1  col2  col3
    #  <int> <chr> <int> <int> <int>
    #1     1 0         0     2     3
    #2     1 1         1     2     4
    #3     1 2         3     3     5
    #4     2 0         1     2     4
    #5     2 1         1     4     5
    #6     2 2         2     7     5
    

    数据

    df1 <- structure(list(id = 1:2, col1_0 = 0:1, col1_1 = c(1L, 1L), col1_2 = 3:2, 
        col2_0 = c(2L, 2L), col2_1 = c(2L, 4L), col2_2 = c(3L, 7L
        ), col3_0 = 3:4, col3_1 = 4:5, col3_2 = c(5L, 5L)), 
        class = "data.frame", row.names = c(NA, 
    -2L))
    

    【讨论】:

      【解决方案2】:

      这是使用reshape 的基本R 选项,其中timevar="x" 创建一个名为x 的列,sep="_" 帮助获取原始列名称的最后一个数字。

      res <- reshape(
        df,
        direction = "long",
        idvar = "id",
        varying = -1,
        timevar = "x",
        sep = "_"
      )
      res <- res[order(res$id), ]
      
      • 输出
      > res
          id x col1 col2 col3
      1.0  1 0    0    2    3
      1.1  1 1    1    2    4
      1.2  1 2    3    3    5
      2.0  2 0    1    2    4
      2.1  2 1    1    4    5
      2.2  2 2    2    7    5
      

      数据

      > dput(df)
      structure(list(id = 1:2, col1_0 = 0:1, col1_1 = c(1L, 1L), col1_2 = 3:2,
          col2_0 = c(2L, 2L), col2_1 = c(2L, 4L), col2_2 = c(3L, 7L
          ), col3_0 = 3:4, col3_1 = 4:5, col3_2 = c(5L, 5L)), class = "data.frame", row.names = c(NA, 
      -2L))
      

      【讨论】:

        猜你喜欢
        • 2023-03-19
        • 2018-02-14
        • 2021-12-24
        • 2017-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多