1

I have a list with several data frames of different taxa. The df's for the different taxa are of different length and have different names for columns with the "same information", e.g. "abundance", "abund", "individuals". I show you an example:

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

In my original list, I have much more dfs.. What I want to do is to iterate through the dfs and change all colnames with "abund" or "individuals" to "abundance", if not already.

If I have a list with just one df lst %>% map(rename, abundance = abund) works fine, but with more dfs and different colnames, it says:

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

I tried several codes:

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

and many others with map_if, map_at, rename_if, rename_at, etc., but nothing worked.

1
  • 1
    You have many errors in your sample data, including: C instead of c; unclosed rep(.); unclosed data.frame(.). It helps to try your own code in a fresh R instance before finishing questions. Commented Sep 15, 2021 at 15:12

1 Answer 1

5

dplyr::rename_with() applies a function to each column name. In that function we can check if the name contains “abund” or “individuals” with grepl() and then those columns get renamed. The columns that don’t contain the strings we are looking for technically also get renamed, but they receive their old name again, so nothing is changed there.

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

Instead of using tidyverse style anonymous functions we can use the new base R anonymous function style in order to make the code a bit more comprehensible.

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
Sign up to request clarification or add additional context in comments.

1 Comment

where does the df come from in the base R version?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.