我有一个数据集,每行中有多个不同范围的列(每行对应一个单独的列(,如下所示。不同列类型的每个实例都有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
来完成。注意.value
和x
的顺序。这意味着该列的值应该进入_
之前的每个前缀,并且带有后缀存根的新列进入"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))