r - 有效地将数据从宽格式转换为长格式,并将多列组合成新变量
问题描述
我必须重塑一个由观察(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
并包含所有元素编号。所以,太好了。例如,这可以很容易地gather
从tidyr
包中实现:
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
在最终数据中的变量中转换原始数据中的变量怎么办?
解决方案
正如@domaeg 在评论中指出的那样,这可以通过以下新pivot_longer
功能来完成tidyr 1.0.0
:
library(tidyverse)
data %>% pivot_longer(-obs_id,
names_to = "p",
names_pattern = "p([0-9])",
values_to = "char")
产生:
# A tibble: 9 x 3
obs_id p char
<int> <chr> <int>
1 1 1 20
2 1 2 12
3 1 3 16
4 2 1 16
5 2 2 20
6 2 3 11
7 3 1 18
8 3 2 16
9 3 3 13
为了更好的衡量,我无法用种子复制你的数据,所以我直接这样设置它,如果其他人想要一个镜头:
txt <- "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"
data <- read.table(text = txt, header = TRUE)
推荐阅读
- google-sheets - 在“Countifs”公式Google表格中使用“and”和“or”逻辑
- ios - 如何防止字体真棒在ios swift中更改文本
- c# - 我可以检索只有 google sheet api v4 .net 标题名称的电子表格吗?
- opencv - VR耳机上的OpenGL渲染图像
- swift - Swift 自定义转换不起作用(未调用 UIViewControllerTransitioningDelegate)
- spring-boot - SpringBoot/Spring Cloud Config Client 多个应用程序上下文(根和 servlet),带有 RefreshScope 注释 bean
- vtk - vtkCamera 焦点期望的值的类型和范围是什么?
- c# - CheckListBox SelectedItems.Count 并不总是有效
- php - 空白页和内存大小耗尽
- swift - Eureka - SelectorViewController 上的自定义单元格