R:将列名中的年份转换为新行

0sgqnhkj  于 2023-01-22  发布在  其他
关注(0)|答案(2)|浏览(107)

如何在ID列以外的列中标识在每列末尾指定的年份(跟在各种字符后面),然后将相应的行放置在新数据框中,并将该年份表示为新列,最后得到一个新列,该新列只需从原始列名中删除年份,并消除列名末尾出现的任何下划线?
例如,我想转换一个包含2条记录和5列(分别为col1、col2_1980、col2_1981、col3_1980和col3_1981,其中col1是字符值)的数据框(“a”或“B”)转换成具有4个记录的 Dataframe ,其中对于2个记录COL1 =“a”,对于2个记录COL1 =“b”,然后col2 =“1980”表示每个col1值的1个记录,col2 =“1981”表示每个col1值的1个记录。
如果我可以使用一个公式来捕获年份,那么使用tidyr::separate()可能会有效,如下所示:

substr(colnames(df1),
         nchar(colnames(df1)) - 3,
         nchar(colnames(df1)))

原件

set.seed(3)
df1 <-
  rbind(
  data.frame(
      col1 = "a", 
      col2_1_1980 = runif(1), 
      col2_1_1981 = runif(1), 
      col3_1_1980 = runif(1), 
      col3_1_1981 = runif(1)),
  data.frame(  
      col1 = "b", 
      col2_1_1980 = runif(1), 
      col2_1_1981 = runif(1), 
      col3_1_1980 = runif(1), 
      col3_1_1981 = runif(1)))

  col1 col2_1_1980 col2_1_1981 col3_1_1980 col3_1_1981
1    a   0.1680415   0.8075164   0.3849424   0.3277343
2    b   0.6021007   0.6043941   0.1246334   0.2946009

目标

qacovj5a

qacovj5a1#

pivot_longer()可以处理名称中的模式/分隔符。
使用更新的数据集:

library(dplyr)
library(tidyr)

set.seed(3)
df1 <-
  rbind(
    data.frame(
      col1 = "a", 
      col2_1_1980 = runif(1), 
      col2_1_1981 = runif(1), 
      col3_1_1980 = runif(1), 
      col3_1_1981 = runif(1)),
    data.frame(  
      col1 = "b", 
      col2_1_1980 = runif(1), 
      col2_1_1981 = runif(1), 
      col3_1_1980 = runif(1), 
      col3_1_1981 = runif(1)))

df1 %>% pivot_longer(
  cols = contains("_"), 
  names_pattern = "(.*)_(\\d+)$", 
  names_to = c(".value", "year"))
#> # A tibble: 4 × 4
#>   col1  year  col2_1 col3_1
#>   <chr> <chr>  <dbl>  <dbl>
#> 1 a     1980   0.168  0.385
#> 2 a     1981   0.808  0.328
#> 3 b     1980   0.602  0.125
#> 4 b     1981   0.604  0.295

所讨论的原始样本数据包括诸如col2_1980col2_1981之类的列名,对于那些names_sep参数很有用的列名:

df1 %>% pivot_longer(
  cols = contains("_"), 
  names_sep = "_", 
  names_to = c(".value", "year"))
#> # A tibble: 4 × 4
#>   col1  year   col2  col3
#>   <chr> <chr> <dbl> <dbl>
#> 1 a     1980  0.168 0.385
#> 2 a     1981  0.808 0.328
#> 3 b     1980  0.602 0.125
#> 4 b     1981  0.604 0.295

创建于2023年1月18日,使用reprex v2.0.2

6mzjoqzu

6mzjoqzu2#

请尝试下面的代码,使用pivot_longger、pivot_wideer实现预期结果
编号

library(dplyr)

df2 <- df1 %>% pivot_longer(c(contains('_'))) %>% 
mutate(year=str_extract(name,'(?<=\\_)\\d.*'), name=str_extract(name,'^.*(?=\\_)')) %>% 
pivot_wider(c(col1,year), names_from = 'name', values_from = 'value')

相关问题