使用purrr重命名多个数据帧列

时间:2017-10-07 04:09:21

标签: r tidyverse purrr

我有以下数据框列表,其中包含名为cyl

的列
# Create 3 dataframes with identical column names
mt_list <- list(head(mtcars[, 1:2]), tail(mtcars[, 1:2]), mtcars[13:18, 1:2])
mt_list
#> [[1]]
#>                    mpg cyl
#> Mazda RX4         21.0   6
#> Mazda RX4 Wag     21.0   6
#> Datsun 710        22.8   4
#> Hornet 4 Drive    21.4   6
#> Hornet Sportabout 18.7   8
#> Valiant           18.1   6
#> 
#> [[2]]
#>                 mpg cyl
#> Porsche 914-2  26.0   4
#> Lotus Europa   30.4   4
#> Ford Pantera L 15.8   8
#> Ferrari Dino   19.7   6
#> Maserati Bora  15.0   8
#> Volvo 142E     21.4   4
#> 
#> [[3]]
#>                      mpg cyl
#> Merc 450SL          17.3   8
#> Merc 450SLC         15.2   8
#> Cadillac Fleetwood  10.4   8
#> Lincoln Continental 10.4   8
#> Chrysler Imperial   14.7   8
#> Fiat 128            32.4   4

# New 'cyl' column names to change to (they are a character vector)
new_cyl_names <- c("cyl1", "cyl2", "cyl3")
new_cyl_names
#> [1] "cyl1" "cyl2" "cyl3"

我想将cyl命名为字符向量new_cyl_names中的对应值。

我尝试按如下方式执行此操作:

# Custom function to change cyl to the 
# character value contained in new_colname
change_colname_cyl <- function(df, new_colname){
    df %>% 
        dplyr::rename(new_colname = cyl)
}

# The following should change the names to cyl1, cyl2, cyl3
purrr::map2(.x = mt_list, .y = new_cyl_names, ~ change_colname_cyl(.x, .y))

这导致(仅显示第一个数据框):

[[1]]
                   mpg new_colname
Mazda RX4         21.0           6
Mazda RX4 Wag     21.0           6
Datsun 710        22.8           4
Hornet 4 Drive    21.4           6
Hornet Sportabout 18.7           8
Valiant           18.1           6

有人可以帮我正确使用purrr,即在这种情况下将cyl更改为cyl1而不是new_colname以上吗?

2 个答案:

答案 0 :(得分:5)

我对你的功能稍作修改。我认为现在它有效。请参阅此https://cran.r-project.org/web/packages/dplyr/vignettes/programming.html)以了解有关dplyr中标准评估和非标准评估的更多信息。

library(tidyverse)

# List of data frames
mt_list <- list(head(mtcars[, 1:2]), tail(mtcars[, 1:2]), mtcars[13:18, 1:2])

# New column names
new_cyl_names <- c("cyl1", "cyl2", "cyl3")

# Create the function
change_colname_cyl <- function(df, new_colname){
  df %>% rename(!!new_colname := cyl)
}

# Apply the function
map2(mt_list, new_cyl_names, ~ change_colname_cyl(.x, .y))
[[1]]
                   mpg cyl1
Mazda RX4         21.0    6
Mazda RX4 Wag     21.0    6
Datsun 710        22.8    4
Hornet 4 Drive    21.4    6
Hornet Sportabout 18.7    8
Valiant           18.1    6

[[2]]
                mpg cyl2
Porsche 914-2  26.0    4
Lotus Europa   30.4    4
Ford Pantera L 15.8    8
Ferrari Dino   19.7    6
Maserati Bora  15.0    8
Volvo 142E     21.4    4

[[3]]
                     mpg cyl3
Merc 450SL          17.3    8
Merc 450SLC         15.2    8
Cadillac Fleetwood  10.4    8
Lincoln Continental 10.4    8
Chrysler Imperial   14.7    8
Fiat 128            32.4    4

更新

基于保罗的评论。以下似乎是重命名列的更直接和简洁的方法。

map2(mt_list, new_cyl_names, ~rename(.x, !!.y := cyl))

答案 1 :(得分:3)

我们可以使用setnames

中的data.table
library(data.table)
library(tidyverse)
map2(mt_list, new_cyl_names, ~setnames(.x, 'cyl', .y))
mt_list
#[[1]]
#                   mpg cyl1
#Mazda RX4         21.0    6
#Mazda RX4 Wag     21.0    6
#Datsun 710        22.8    4
#Hornet 4 Drive    21.4    6
#Hornet Sportabout 18.7    8
#Valiant           18.1    6

#[[2]]
#                mpg cyl2
#Porsche 914-2  26.0    4
#Lotus Europa   30.4    4
#Ford Pantera L 15.8    8
#Ferrari Dino   19.7    6
#Maserati Bora  15.0    8
#Volvo 142E     21.4    4

#[[3]]
#                     mpg cyl3
#Merc 450SL          17.3    8
#Merc 450SLC         15.2    8
#Cadillac Fleetwood  10.4    8
#Lincoln Continental 10.4    8
#Chrysler Imperial   14.7    8
#Fiat 128            32.4    4