将 pivot_longer 与多个变量一起使用时,我丢失了常量变量(包括 id)

I lose the constant variables (including id) when using pivot_longer with multiple variables

我尝试重塑以下

country region abc2001 abc2002 xyz2001 xyz2002
Japan East Asia 1 2 4.5 5.5

以下

country region year abc xyz
Japan East Asia 2001 1 4.5
Japan East Asia 2002 2 5.5

其实同理还有五个变量

我使用以下代码:

long <- data %>% pivot_longer(cols = c(-country, -region), names_to = c(".value", "year"), names_pattern = "([^\.]*)\.*(\d{4})")

除了丢失国家和地区变量外,结果是数据的长版本。我做错了什么?或者我还能如何做得更好?

提前致谢。

我们可能会更改正则表达式模式以匹配一个或多个 non-digits(\D+) 作为第一个捕获组,并匹配一个或多个数字 (\d+) 作为第二个

librarytidyr)
pivot_longer(data, cols = c(-country, -region),
    names_to = c(".value", "year"), names_pattern = "(\D+)(\d+)")

-输出

# A tibble: 2 × 5
  country region    year    abc   xyz
  <chr>   <chr>     <chr> <int> <dbl>
1 Japan   East Asia 2001      1   4.5
2 Japan   East Asia 2002      2   5.5

数据

data <- structure(list(country = "Japan", region = "East Asia", abc2001 = 1L, 
    abc2002 = 2L, xyz2001 = 4.5, xyz2002 = 5.5), 
class = "data.frame", row.names = c(NA, 
-1L))

更新: 如@akrun 所述,请参阅评论,这里有更好的正则表达式和环顾四周:

rename_with(., ~str_replace(names(data), "(?<=\D)(?=\d)", "\_"))

第一个回答:

这是 names_sep 的版本。挑战在于在列名中添加下划线。 首选答案是@akrun:

  • (.*) - 第 1 组:尽可能多的任意零个或多个字符
  • (\d{4}$) - 第 2 组:末尾的数字
library(dplyr)
library(tidyr)

data %>% 
  rename_with(., ~sub("(.*)(\d{4}$)", "\1_\2", names(data))) %>% 
  pivot_longer(-c(country, region),
             names_to =c(".value","Year"),
             names_sep ="_"
             )
  country region    Year    abc   xyz
  <chr>   <chr>     <chr> <int> <dbl>
1 Japan   East Asia 2001      1   4.5
2 Japan   East Asia 2002      2   5.5