R pivot_longer 带有存根名称和最后一个下划线

R pivot_longer with stub names and by last underscore

我有以下程式化的宽数据框 df_wide,我想在 R 中重塑长数据框:

df_wide = data.frame(country = c("A", "B"),
                gdp_1999 = c(100, 200),
                gdp_2000 = c(400,500),
                poverty_rate_1999 = c(35,40),
                poverty_rate_2000 = c(10,15),
                inequality_score_gini_1999 = c(20,25),
                inequality_score_gini_2000 = c(40,45)
                )
df_wide
  country gdp_1999 gdp_2000 poverty_rate_1999 poverty_rate_2000 inequality_score_gini_1999 inequality_score_gini_2000
1       A      100      400                35                10                         20                         40
2       B      200      500                40                15                         25                         45

我想使用 pivot_longer 按国家/地区年份重塑数据,使数据框看起来像这样:

df_long = data.frame(country = c("A","A","B","B"),
                     year = c(1999,1999,2000,2000),
                     gdp = c(100,400,200,500),
                     poverty_rate = c(35,10,40,15),
                     inequality_score_gini = c(20,40,25,45))
df_long
country year gdp poverty_rate inequality_score_gini
1       A 1999 100           35                    20
2       A 1999 400           10                    40
3       B 2000 200           40                    25
4       B 2000 500           15                    45

我如何用 pivot_longer 做到这一点?请注意,我特别选择了具有不同数量下划线的变量,因为相关 没有为我的数据集提供足够的指导。我能做的最好的就是使用常规 reshape,一次重塑一个存根模式,例如:

library(reshape)
long_data_gdp <- reshape(df_wide, 
                     varying = c("gdp_1999", "gdp_2000"),
                     idvar = "country",
                     direction = "long",
                     sep = "_")

如果正确答案可以提供两个子答案,我将不胜感激:(1) starts_with() 的答案,这样一切都可以通过存根名称而不是 names_pattern 来完成,因为我的尝试above with reshape 当有多个下划线分隔符时失败(即 poverty_rateinequality_gini_score 不起作用); (2) names_pattern 的答案,但解释了如何以非 regex 专家易于理解的方式将最后一个下划线作为分隔符。

这回答了 names_pattern 方法:

诀窍是使用设置两组的正则表达式:(1) 所有值变量 (.*) 和 (2) 年份变量 ([0-9]{4})。我们需要使用括号来指定组。

library(tidyverse)

df_wide %>% 
  pivot_longer(cols = !country,
               names_to = c(".value", "year"),
               names_pattern = "^(.*)_([0-9]{4})$")

#> # A tibble: 4 × 5
#>   country year    gdp poverty_rate inequality_score_gini
#>   <chr>   <chr> <dbl>        <dbl>                 <dbl>
#> 1 A       1999    100           35                    20
#> 2 A       2000    400           10                    40
#> 3 B       1999    200           40                    25
#> 4 B       2000    500           15                    45

reprex package (v0.3.0)

于 2022-04-30 创建

下方数据:

df_wide <- tribble(~country, ~gdp_1999, ~gdp_2000, ~poverty_rate_1999, ~poverty_rate_2000, ~inequality_score_gini_1999, ~inequality_score_gini_2000,
                   "A",      100,      400,                35,                10,                         20,                         40,
                   "B",      200,      500,                40,                15,                         25,                         45)