当时间指示器位于 R 中的列名中间时,透视更长的数据

Posted

技术标签:

【中文标题】当时间指示器位于 R 中的列名中间时,透视更长的数据【英文标题】:Pivot longer data when time indicator is in middle of column name in R 【发布时间】:2022-01-10 00:25:46 【问题描述】:

由于“时间”指示符位于列名称的中间,因此我无法将数据延长到更长的时间。 所以这就是数据的样子:

data
  id wei4_mz kpx_2350flag kpx_3730 var1_190f var2_190f var3_190f var1_430va var2_430va var3_430va
1  1       2            2        1         1         0         1          a          b          c
2  2       3            2        1         1        NA         1          b          b          b
3  3       4            4        2         1         1         0          a          b          a
4  4       1            2       NA         1         1         1          b          z          b
5  5       2            1        0         1         1         1          z          z          b

我想要的是旋转所有以“var”开头的列,并根据它们在“var”之后和“_”之前取的值来拆分它们,基本上是数字 1:3。我还想将这些数字添加到新的列名wave。这样我就可以拥有这样的东西:

    id wave kpx_2350flag kpx_3730 var_190f var_430va
1   1    1            2        1        1         a
2   1    2            2        1        0         b
3   1    3            2        1        1         c
4   2    1            2        1        1         b
5   2    2            2        1        1         b
6   2    3            2        1       NA         b
7   3    1            4        2        1         a
8   3    2            4        2        1         b
9   3    3            4        2        0         a
10  4    1            2       NA        1         b
11  4    2            2       NA        1         z
12  4    3            2       NA        1         b
13  5    1            1        0        1         z
14  5    2            1        0        1         z
15  5    3            1        0        1         b

这是创建两个 dfs 的代码:

    data <- data.frame(id = c(1:5),
                   wei4_mz = c(2, 3, 4, 1, 2),
                   kpx_2350flag = c(2, 2, 4, 2, 1),
                   kpx_3730 = c(1, 1, 2, NA, 0),
                   var1_190f = c(1, 1, 1, 1, 1),
                   var2_190f = c(0, NA, 1, 1, 1),
                   var3_190f = c(1, 1, 0, 1, 1),
                   var1_430va = c("a", "b", "a", "b", "z"),
                   var2_430va = c("b", "b", "b", "z", "z"),
                   var3_430va = c("c", "b", "a", "b", "b"))
ideal <- data.frame( id = c(1, 1, 1,
                             2, 2, 2, 
                             3, 3, 3,
                             4, 4,4, 
                             5, 5, 5),
                     wave = c(1, 2, 3,
                              1, 2, 3,
                              1, 2, 3,
                              1, 2, 3,
                              1, 2, 3),
                     kpx_2350flag = c(2, 2,2,
                                      2, 2,2,
                                      4, 4,4,
                                      2, 2,2,
                                      1, 1,1
                                      ),
                     kpx_3730 = c( 1, 1,1, 
                                  1,1, 1,
                                  2,2,2,
                                  NA, NA, NA,
                                  0, 0, 0),
                     var_190f = c( 1, 0, 1,
                                   1, 1, NA,
                                   1, 1, 0,
                                   1, 1, 1,
                                   1, 1, 1),
                     var_430va = c("a", "b", "c",
                                   "b", "b", "b",
                                   "a", "b", "a",
                                   "b", "z", "b",
                                   "z", "z", "b"))

关于如何解决这个问题的任何想法?真的有很多事情要做。

谢谢!

【问题讨论】:

【参考方案1】:

在使用str_replace 重新排列“vars..”列的列名子字符串后,我们可以使用pivot_longer

library(stringr)
library(dplyr)
library(tidyr)
data %>% 
   rename_with(~ str_replace(., "(\\d+)(_.*)", "\\2:\\1"), 
       starts_with('var')) %>% 
   pivot_longer(cols = starts_with('var'), names_to = c(".value", "wave"), 
        names_pattern = "(.*):(\\d+)")

-输出

# A tibble: 15 × 7
      id wei4_mz kpx_2350flag kpx_3730 wave  var_190f var_430va
   <int>   <dbl>        <dbl>    <dbl> <chr>    <dbl> <chr>    
 1     1       2            2        1 1            1 a        
 2     1       2            2        1 2            0 b        
 3     1       2            2        1 3            1 c        
 4     2       3            2        1 1            1 b        
 5     2       3            2        1 2           NA b        
 6     2       3            2        1 3            1 b        
 7     3       4            4        2 1            1 a        
 8     3       4            4        2 2            1 b        
 9     3       4            4        2 3            0 a        
10     4       1            2       NA 1            1 b        
11     4       1            2       NA 2            1 z        
12     4       1            2       NA 3            1 b        
13     5       2            1        0 1            1 z        
14     5       2            1        0 2            1 z        
15     5       2            1        0 3            1 b        

【讨论】:

太棒了。非常感谢!我在 Q 中忘记提到的一件事是,我想将标识时间的数字添加到输出中名为“wave”的列中。我编辑了抱歉。但是你会怎么做呢?

以上是关于当时间指示器位于 R 中的列名中间时,透视更长的数据的主要内容,如果未能解决你的问题,请参考以下文章

当按钮按下需要更长的时间时,Windows 会变暗

为啥检查错误的密码比检查正确的密码要花更长的时间?

为啥偶数 N 比奇数 N 花费更长的时间?

使用 ARM NEON 执行比 C 代码需要更长的时间

当我包含验证数据时,为啥模型训练需要更长的时间?

SQL-query 在代码中比直接查询 db 花费更长的时间