根据条件重命名列表元素

Rename elements of list based on condition

我有一个巨大的列表 samplelist,其中包含各种小标题(在名为 AlphaBetaGamma 的简化示例中)。每个 tibble 包含各种元素(在示例中称为 sample_0sample_1)。但是,并非每个 tibble 都包含每个元素(Gamma 仅包含 sample_0,但不包含 sample_1)。我想做的是根据条件重命名元素:如果小标题中有元素 sample_1,则将其重命名为 sampling。但是,如果小标题不包含 sample_1,请将 sample_0 重命名为 sampling(这样列表现在包含每个小标题的名为 sampling 的元素)。

samplelist <- list(Alpha = structure(list(sample_0 = c(3, NA, 7, 9, 2),
                                     sample_1 = c(NA, 8, 5, 4, NA)),
                                row.names = c(NA, -5L),
                                class = c("tbl_df", "tbl", "data.frame")),
              Beta = structure (list(sample_0 = c(2, 9, NA, 3, 7),
                                     sample_1 = c(3, 7, 9, 3, NA)),
                                row.names = c(NA, -5L),
                                class = c("tbl_df", "tbl", "data.frame")),
              Gamma = structure(list(sample_0 = c(NA, NA, 4, 6, 3)),
                                row.names = c(NA, -5L),
                                class = c("tbl_df", "tbl", "data.frame")))

有人知道如何获得以下所需的输出吗?

samplelist
$Alpha
# A tibble: 5 x 2
  sample_0 sampling
     <dbl>    <dbl>
1        3       NA
2       NA        8
3        7        5
4        9        4
5        2       NA

$Beta
# A tibble: 5 x 2
  sample_0 sampling
     <dbl>    <dbl>
1        2        3
2        9        7
3       NA        9
4        3        3
5        7       NA

$Gamma
# A tibble: 5 x 1
       sampling
          <dbl>
  1          NA
  2          NA
  3           4
  4           6
  5           3

编辑 使用@akrun提供的代码:

map(errorlist,  ~  if(ncol(.x) == 1 && names(.x) == 'sample_0')
      setNames(.x, 'sampling') else 
      rename_with(.x, ~ 'sampling', matches('sample_1')))

我的样本列表得到了不理想的输出。但是,如果 Gamma 中有多个组,(调整后的)代码仅适用于 AlphaBeta,但 Gamma 保持不变(添加 Delta从编辑前):

errorlist <- list(Alpha = structure(list(sample_0 = c(3, NA, 7, 9, 2),
                                         sample_1 = c(NA, 8, 5, 4, NA),
                                         sample_2 = c(7, 3, 5, NA, NA)),
                                    row.names = c(NA, -5L),
                                    class = c("tbl_df", "tbl", "data.frame")),
                  Beta = structure (list(sample_0 = c(2, 9, NA, 3, 7),
                                         sample_1 = c(3, 7, 9, 3, NA),
                                         sample_2 = c(4, 2, 6, 4, 6)),
                                    row.names = c(NA, -5L),
                                    class = c("tbl_df", "tbl", "data.frame")),
                  Gamma = structure(list(sample_0 = c(NA, NA, 4, 6, 3),
                                         sample_1 = c(3, 7, 3, NA, 8)),
                                    row.names = c(NA, -5L),
                                    class = c("tbl_df", "tbl", "data.frame")),
                  Delta = structure (list(error = c(3, 7, 9, 3, NA)),
                                     row.names = c(NA, -5L),
                                     class = c("tbl_df", "tbl", "data.frame")))

map(errorlist,  ~  if(ncol(.x) == 1 && names(.x) == 'sample_1')
  setNames(.x, 'sampling') else 
    rename_with(.x, ~ 'sampling', matches('sample_2')))

输出:

$Alpha
# A tibble: 5 x 3
  sample_0 sample_1 sampling
     <dbl>    <dbl>    <dbl>
1        3       NA        7
2       NA        8        3
3        7        5        5
4        9        4       NA
5        2       NA       NA

$Beta
# A tibble: 5 x 3
  sample_0 sample_1 sampling
     <dbl>    <dbl>    <dbl>
1        2        3        4
2        9        7        2
3       NA        9        6
4        3        3        4
5        7       NA        6

$Gamma
# A tibble: 5 x 2
  sample_0 sample_1
     <dbl>    <dbl>
1       NA        3
2       NA        7
3        4        3
4        6       NA
5        3        8

$Delta
# A tibble: 5 x 1
  error
  <dbl>
1     3
2     7
3     9
4     3
5    NA

这是一个选项 - 使用 map 遍历 list 并使用条件 (if/else) 进行更改(这里,我们使用 errorlist 作为它更通用。它也适用于 samplelist)

library(dplyr)
library(purrr)
map(errorlist,  ~  if(ncol(.x) == 1 && names(.x) == 'sample_0')
      setNames(.x, 'sampling') else 
      rename_with(.x, ~ 'sampling', matches('sample_1')))

-输出

$Alpha
# A tibble: 5 × 2
  sample_0 sampling
     <dbl>    <dbl>
1        3       NA
2       NA        8
3        7        5
4        9        4
5        2       NA

$Beta
# A tibble: 5 × 2
  sample_0 sampling
     <dbl>    <dbl>
1        2        3
2        9        7
3       NA        9
4        3        3
5        7       NA

$Gamma
# A tibble: 5 × 1
  sampling
     <dbl>
1       NA
2       NA
3        4
4        6
5        3

$Delta
# A tibble: 5 × 1
  error
  <dbl>
1     3
2     7
3     9
4     3
5    NA

更新

根据 OP 的评论

lapply(errorlist, \(x) {
  nm1 <- stringr::str_subset(names(x), "^sample_\d+$")
  i1 <- which.max(as.numeric(stringr::str_extract(nm1, 
       "(?<=sample_)\d+")))
   if(length(i1) > 0) names(x)[names(x) == nm1[i1]] <- "sampling"
   x})

-输出

$Alpha
# A tibble: 5 × 3
  sample_0 sample_1 sampling
     <dbl>    <dbl>    <dbl>
1        3       NA        7
2       NA        8        3
3        7        5        5
4        9        4       NA
5        2       NA       NA

$Beta
# A tibble: 5 × 3
  sample_0 sample_1 sampling
     <dbl>    <dbl>    <dbl>
1        2        3        4
2        9        7        2
3       NA        9        6
4        3        3        4
5        7       NA        6

$Gamma
# A tibble: 5 × 2
  sample_0 sampling
     <dbl>    <dbl>
1       NA        3
2       NA        7
3        4        3
4        6       NA
5        3        8

$Delta
# A tibble: 5 × 1
  error
  <dbl>
1     3
2     7
3     9
4     3
5    NA