[英]How to rename selected columns using dplyr with new column names as strings
[英]How to rename multiple columns that have numeric column names using dplyr?
假設我有一個 dataframe,其中有幾列將實際數值作為列名而不是基於文本的列名。 例如,列名將是`2015`
而不是"2015"
。
這是一個可重現的例子:
my_df = structure(list(Col1 = c('a', 'b', 'c'),
Col2 = c('d', 'e', 'f'),
`2015` = c('g','h','i'),
`2016` = c('j','k','l'),
`2017` = c('m','n','o'),
`2018` = c('p','q','r'),
`2019` = c('s','t','u'),
`2020` = c('v','w','x'),
`2021` = c('y','z','zz')),
row.names = c(NA, -3L),
class = c("tbl_df", "tbl", "data.frame"))
進一步假設我想將所有數字列名稱重命名為更友好的名稱。 例如,從`2015`
到"XYZ_2015"
(注意轉換為字符串)以及對列`2016`
、 `2017`
、... `2021`
的類似轉換。
如何以使用 dplyr 的管道運算符 ( %>%
) 的方式執行此列重命名,而不需要我手動將它們全部寫出來?
到目前為止,我的方法是“手動”執行此操作,分別重命名每一列:
new_df = my_df %>%
rename(XYZ_2015 = `2015`,
XYZ_2016 = `2016`,
XYZ_2017 = `2017`,
XYZ_2018 = `2018`,
XYZ_2019 = `2019`,
XYZ_2020 = `2020`,
XYZ_2021 = `2021`)
但是,這種方法比較麻煩,而且容易出錯。 有沒有辦法讓我以更自動化的方式這樣做? 我覺得 for 循環可以在這里工作,但我無法弄清楚使 for 循環的變量與反引號配合得很好的語法。
例如,我試過這個:
for(year in 2015:2021){
print(year)
new_colname = paste0('XYZ_',year)
my_df = my_df %>% rename(`new_colname` = `year`)
}
但這會產生一個錯誤:
Error in `stop_subscript()`:
! Can't rename columns that don't exist.
x Location 2015 doesn't exist.
i There are only 9 columns.
---
Backtrace:
1. my_df %>% rename(new_colname = year)
3. dplyr:::rename.data.frame(., new_colname = year)
4. tidyselect::eval_rename(expr(c(...)), .data)
5. tidyselect:::rename_impl(...)
6. tidyselect:::eval_select_impl(...)
15. tidyselect:::vars_select_eval(...)
16. tidyselect:::loc_validate(pos, vars, call = error_call)
17. vctrs::vec_as_location(pos, n = length(vars))
18. vctrs `<fn>`()
19. vctrs:::stop_subscript_oob(...)
20. vctrs:::stop_subscript(...)
我們可以使用rename_with
並paste
( str_c
)帶有列名( .x
)的前綴XYZ_
僅適用於與從開始( ^
)到結束( $
)的 4 位( \\d{4}
)列名matches
的列名字符串的
library(dplyr)
library(stringr)
my_df %>%
rename_with(~ str_c("XYZ_", .x), matches("^\\d{4}$"))
-輸出
# A tibble: 3 × 9
Col1 Col2 XYZ_2015 XYZ_2016 XYZ_2017 XYZ_2018 XYZ_2019 XYZ_2020 XYZ_2021
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 a d g j m p s v y
2 b e h k n q t w z
3 c f i l o r u x zz
請注意, rename_with
用法是
rename_with(.data, .fn, .cols = everything(), ...)
和.cols
指定為
.cols - <<tidy-select>> 要重命名的列; 默認為所有列。
這意味着我們可以使用任何tidy-select
輔助函數( matches/starts_with/ends_with/everything()
)等來選擇列
或者使用base R
names(my_df) <- sub("^X", "XYZ_", make.names(names(my_df)))
不是那么優雅和有點hacky的方式:
library(dplyr)
my_colnames <- paste("XYZ", colnames(my_df[-c(1:2)]))
my_df %>%
rename(!!!setNames(names(.[-c(1:2)]), my_colnames))
Col1 Col2 `XYZ 2015` `XYZ 2016` `XYZ 2017` XYZ 2…¹ XYZ 2…² XYZ 2…³ XYZ 2…⁴
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 a d g j m p s v y
2 b e h k n q t w z
3 c f i l o r u x zz
# … with abbreviated variable names ¹`XYZ 2018`, ²`XYZ 2019`, ³`XYZ 2020`,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.