首页 > 解决方案 > 如何在 pivot_longer 中使用 names_pattern?

问题描述

假设我有这段代码试图从 df 中提取 x 和 y:

df <- data.frame(
  num = c(1,2),
  x_cap = c(4,5),
  x_cap_rolling = c(4.4,5.5),
  y_cap = c(7,8),
  y_cap_rolling = c(7.7,8.8)
)

df_long <- df %>% pivot_longer(cols=!num,
               names_pattern = "(.+)_cap",
               names_to = "type", values_to="cap")

它得到:

> df_long
# A tibble: 8 x 3
    num type    cap
  <dbl> <chr> <dbl>
1     1 x       4  
2     1 x       4.4
3     1 y       7  
4     1 y       7.7
5     2 x       5  
6     2 x       5.5
7     2 y       8  
8     2 y       8.8

嗯,关闭,但我希望 cap 4 的类型为“x”,cap 4.4 的类型为“x_rolling”,依此类推。

以下是一些失败的尝试:

df_long <- df %>% pivot_longer(cols=!num,
               names_pattern = "(.+)_cap(_rolling)*",
               names_to = "type", values_to="cap")

df_long <- df %>% pivot_longer(cols=!num,
               names_pattern = "(.+)_cap(.*)",
               names_to = "type", values_to="cap")

每个都返回错误:

Error: `regex` should define 1 groups;  found.

我不明白这个错误。

如何在适当的行中提取类型为 x、x_rolling、y、y_rolling 的结果?

标签: rtidyversetidyr

解决方案


由于我们要捕获的值没有按顺序对齐,您可以先根据我们要提取的数据重命名列,然后再将其转换为长格式,或者获取长格式的数据,然后提取相关文本。

library(dplyr)
library(tidyr)

df %>%
  rename_with(~trimws(sub('cap_?', '', .), whitespace = '_')) %>%
  pivot_longer(cols = -num, 
               names_to = "type", values_to="cap")

#   num type        cap
#  <dbl> <chr>     <dbl>
#1     1 x           4  
#2     1 x_rolling   4.4
#3     1 y           7  
#4     1 y_rolling   7.7
#5     2 x           5  
#6     2 x_rolling   5.5
#7     2 y           8  
#8     2 y_rolling   8.8

推荐阅读