如何在pivot_longer中使用names_pattern?

时间:2020-10-25 00:55:27

标签: r tidyverse tidyr

假设我有这段代码试图从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

嗯,关闭,但是我想将第4章的类型设为“ x”,将第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的结果?

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:1)

我们可以在进行枢轴旋转后mutate

library(dplyr)
library(tidyr)
library(stringr)
df %>% 
   pivot_longer(cols = -num, names_to = "type", values_to = "cap") %>% 
   mutate(type = str_remove(type, "_cap"))

-输出

# A tibble: 8 x 3
#    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