用于将不同列的多个范围从宽格式折叠为长格式的R函数



我有一个数据集,每行中有多个不同范围的列(每行对应一个单独的列(,如下所示。不同列类型的每个实例都有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列,它只保留原始列名的最后一个数字。

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

我们不需要任何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))

这里有一个使用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))

最新更新