按条件更改存储在列表中的数据框的列名

Change column names of data frames stored in a list by condition

我有一个包含不同类群的多个数据框的列表。不同分类单元的 df 具有不同的长度,并且具有“相同信息”的列具有不同的名称,例如“丰富”,“丰富”,“个人”。我给你举个例子:

spiders <- data.frame(plot = c(1,2,3),
                      abundance = c(1,4,8),
                      habitat = c(rep("forest", 3)))

bugs <- data.frame(plot = c(1,2,3),
                   abund = c(1,4,8))

birds<- data.frame(plot = c(1,2,3),
                   individuals= C(1,4,8),
                   habitat = c(rep("forest", 3)),
                   method = c(rep("visual", 3)))

lst <- list("spiders" = spiders, "bugs" = bugs, "birds" = birds)

show(lst)
$spiders
  plot abundance habitat
1    1         1  forest
2    2         4  forest
3    3         8  forest

$bugs
  plot abund
1    1     1
2    2     4
3    3     8

$birds
  plot individuals habitat method
1    1           1  forest visual
2    2           4  forest visual
3    3           8  forest visual

在我原来的列表中,我有更多的 dfs..我想做的是遍历 dfs 并将所有带有“abund”或“individuals”的 colnames 更改为“abundance”,如果还没有的话。

如果我有一个只有一个 df lst %>% map(rename, abundance = abund) 的列表工作正常,但有更多的 df 和不同的 colnames,它说:

error: Can't rename columns that don't exist. x Column abund doesn't exist.

我尝试了几种代码:

lst %>% set_names(~sub("abund", "abundance", names(.x)))
lst %>% set_names(~sub("abund", "abundance", .x))

和许多其他 map_ifmap_atrename_ifrename_at 等,但没有任何效果。

dplyr::rename_with() 对每个列名应用一个函数。在该函数中,我们可以使用 grepl() 检查名称是否包含“abund”或“individuals”,然后这些列将被重命名。不包含我们在技术上寻找的字符串的列也被重命名,但它们再次使用旧名称,因此那里没有任何改变。

library(dplyr)
library(purrr)

map(lst, ~ rename_with(., ~ ifelse(
  grepl("abund|individuals", .), "abundance", .
)))
#> $spiders
#>   plot abundance habitat
#> 1    1         1  forest
#> 2    2         4  forest
#> 3    3         8  forest
#> 
#> $bugs
#>   plot abundance
#> 1    1         1
#> 2    2         4
#> 3    3         8
#> 
#> $birds
#>   plot abundance habitat
#> 1    1         1  forest
#> 2    2         4  forest
#> 3    3         8  forest
#> 4    1         1  visual
#> 5    2         4  visual
#> 6    3         8  visual

我们可以使用新的而不是使用 tidyverse 风格的匿名函数 基本 R 匿名函数样式,以使代码更易于理解。

map(lst, \(df) rename_with(df, \(name) ifelse(
  grepl("abund|individuals", name), "abundance", name
)))
#> $spiders
#>   plot abundance habitat
#> 1    1         1  forest
#> 2    2         4  forest
#> 3    3         8  forest
#> 
#> $bugs
#>   plot abundance
#> 1    1         1
#> 2    2         4
#> 3    3         8
#> 
#> $birds
#>   plot abundance habitat
#> 1    1         1  forest
#> 2    2         4  forest
#> 3    3         8  forest
#> 4    1         1  visual
#> 5    2         4  visual
#> 6    3         8  visual