【发布时间】:2020-03-09 10:09:41
【问题描述】:
我必须重塑一个由观察 (obs) 和与观察相关联的元素 (p) 组成的数据集。元素的数据(特征)在附加到观察结果的新列中。
MWE 如下所示:
set.seed(1)
data <- data.frame(obs_id = c(1:3),
char1 = sample(1:10, 3),
p1 = 1,
p1_char = sample(11:20, 3),
p2 = 2,
p2_char = sample(11:20, 3),
p3 = 3,
p3_char = sample(11:20, 3))
这会产生如下所示的数据:
> data
obs_id p1 p1_char1 p2 p2_char1 p3 p3_char1
1 1 1 20 2 12 3 16
2 2 1 16 2 20 3 11
3 3 1 18 2 16 3 13
obs_id是观察结果。 pX表示各种元素,pX_charX表示特征。
现在,我必须创建带有 两个 新列的长格式数据。第一个应命名为p 并包含所有元素编号。所以,太好了。例如,这可以通过 tidyr 包中的 gather 轻松实现:
library(magrittr)
library(tidyr)
data_long1 <- gather(data, key = p_variable, value = p,
p1, p2, p3)
过滤掉最初的观察,一切都应该是:
> data_long1 %>% filter(obs_id == 1)
obs_id p1_char1 p2_char1 p3_char1 p_variable p
1 1 20 12 16 p1 1
2 1 20 12 16 p2 2
3 1 20 12 16 p3 3
现在,第二个新列应该命名为char 并填充元素的特征。我也可以用gather独立堆叠它们。
data_long2 <- gather(data, key = char_variable, value = char,
p1_char1, p2_char1, p3_char1)
> data_long2 %>% filter(obs_id == 1)
obs_id p1 p2 p3 char_variable char
1 1 1 2 3 p1_char1 20
2 1 1 2 3 p2_char1 12
3 1 1 2 3 p3_char1 16
现在,我可以将两者与bind_cols() 结合起来得到我想要的东西
data_long <- bind_cols(data_long1, data_long2)
> data_long %>%
+ select(obs_id, p, char) %>%
+ filter(obs_id == 1)
obs_id p char
1 1 1 20
2 1 2 12
3 1 3 16
问题是我需要对我想要堆叠的元素的每个新变量执行此操作。
我的问题是这样的:当我从宽到长格式化数据时,有没有更有效的方法来创建两列或更多列?如果我想将原始数据中的 pX_char2 变量转换为最终数据中的 char2 变量怎么办?
【问题讨论】:
-
看看新的
{tidyr}函数pivot_longer()和names_pattern(tidyr.tidyverse.org/articles/…)。我对它们不太熟悉,但这可以解决您的问题。