r语言 - 按列名中的模式组合列



我有一个非常宽的数据框,其中每列存在三次,后缀不同:xxx_A1.5,xxx_A2.0,xxx_A2.5。考虑这个例子:

df1 <- data.frame(col1_A1.5 = c(1,2,3,4), 
col1_A2.0 = c(2,3,4,5),
col1_A2.5 = c(3,4,5,6),
col2_A1.5 = c(10,20,30,40), 
col2_A2.0 = c(20,30,40,50),
col2_A2.5 = c(30,40,50,60))

我现在想把所有的col1_xxx合并到一个列(命名为col1;同样的颜色2等)按照这个图案:col1_A2.0 [colA1.5, colA2.5]。在这个例子中,期望的结果是:

col1           col2
1  "2 [1, 3]"    "20 [10, 30]"
2  "3 [2, 4]"    "30 [20, 40]"
3  "4 [3, 5]"    "40 [30, 50]"
4  "5 [4, 6]"    "50 [40, 60]"

既然我有>100列,我需要一个基于模式的解决方案;我尝试了mutateacross的几种组合,但无法达到预期的结果。有人能给点提示或解决办法吗?提前谢谢。

我在github上维护一个允许使用列模式的包。在这里,我们可以使用dplyover::extract_names提取列模式,并将其作为dplyover::over的输入来遍历模式。在lambda函数中,我们只需要paste0,这里我们可以在.("{.x}_somestring")中使用特殊语法访问变量,其中.x是我们循环的字符串,somestring是变量名的后缀。

df1 <- data.frame(col1_A1.5 = c(1,2,3,4), 
col1_A2.0 = c(2,3,4,5),
col1_A2.5 = c(3,4,5,6),
col2_A1.5 = c(10,20,30,40), 
col2_A2.0 = c(20,30,40,50),
col2_A2.5 = c(30,40,50,60))
library(dplyr)
library(dplyover) # https://github.com/TimTeaFan/dplyover
library(purrr)
df1 %>% 
transmute(over(extract_names("col\d+"),
~ paste0(.("{.x}_A2.0"),
" [", .("{.x}_A1.5"), ", ",
.("{.x}_A2.5"), "]" )))
#>       col1        col2
#> 1 2 [1, 3] 20 [10, 30]
#> 2 3 [2, 4] 30 [20, 40]
#> 3 4 [3, 5] 40 [30, 50]
#> 4 5 [4, 6] 50 [40, 60]

由reprex包(v2.0.1)在2021-09-21创建

**更新**我们可以将上述方法应用于以下注释中给出的数据:

df <- structure(
list(i_cont_AGE__Esti = c(0.0179664619979778),
i_cont_EDUC__Esti = c(-0.0292110157549253),
i_cont_AGE__Q025 = c(0.000824695411111768),
i_cont_EDUC__Q025 = c(-0.0440178234496344),
i_cont_AGE__Q975 = c(0.0346367937813918),
i_cont_EDUC__Q975 = c(-0.014399287910954)),
row.names = c("1"),
class = c("tbl_df", "tbl", "data.frame" ))
library(dplyr)
library(dplyover) # https://github.com/TimTeaFan/dplyover
library(purrr)
df %>% 
transmute(over(extract_names("i_cont_[A-Z]+"),
~ paste0(.("{.x}__Esti"),
" [", .("{.x}__Q025"), ", ",
.("{.x}__Q975"), "]" )))
#> # A tibble: 1 x 2
#>   i_cont_AGE                                                    i_cont_EDUC     
#>   <chr>                                                         <chr>           
#> 1 0.0179664619979778 [0.000824695411111768, 0.0346367937813918] -0.029211015754~

由reprex包(v2.0.1)在2021-09-21创建

您可以使用split.default根据列名中的模式拆分数据框,并使用imap在每个列表中从多个列中创建一个列。

purrr::imap_dfc(split.default(df1, sub('_.*', '', names(df1))), function(x, y) 
tibble::tibble(!!y := sprintf('%d [%d, %d]', 
x[[paste0(y, '_A2.0')]], x[[paste0(y, '_A1.5')]], 
x[[paste0(y, '_A2.5')]])))

#   col1     col2       
#  <chr>    <chr>      
#1 2 [1, 3] 20 [10, 30]
#2 3 [2, 4] 30 [20, 40]
#3 4 [3, 5] 40 [30, 50]
#4 5 [4, 6] 50 [40, 60]  

最新更新