根据条件重命名列表元素
Rename elements of list based on condition
我有一个巨大的列表 samplelist
,其中包含各种小标题(在名为 Alpha
、Beta
和 Gamma
的简化示例中)。每个 tibble 包含各种元素(在示例中称为 sample_0
和 sample_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
中有多个组,(调整后的)代码仅适用于 Alpha
和 Beta
,但 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
我有一个巨大的列表 samplelist
,其中包含各种小标题(在名为 Alpha
、Beta
和 Gamma
的简化示例中)。每个 tibble 包含各种元素(在示例中称为 sample_0
和 sample_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
中有多个组,(调整后的)代码仅适用于 Alpha
和 Beta
,但 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