[英]Rename list columns based on list names with purrr
我有一個命名列表,在該列表中,我想根據列表來自的名稱重命名它們的列。
我的方法的問題似乎是.x
占位符,我認為這將是我唯一的列表名稱。 但在rename_with
function 中,似乎.x
是在每個列表數據幀內評估的,而不是從原始.x
評估的。 有什么方法可以繼承原始的.x
(或列表名稱)進行重命名?
my_list <- list(L1 = data.frame(x=1:3),
L1 = data.frame(x=1:3),
L2 = data.frame(x=1:3),
L2 = data.frame(x=1:3))
my_list |>
purrr::map(.x = unique(names(my_list)),
.f = ~my_list[names(my_list) == .x] |>
dplyr::bind_rows() |>
dplyr::rename_with(.cols = "x",
.fn = ~paste0("new_", .x)))
預期 output:
[[1]]
new_L1
1 1
2 2
3 3
4 1
5 2
6 3
[[2]]
new_L2
1 1
2 2
3 3
4 1
5 2
6 3
只需修改2個地方:
您已經為map()
設置了.x
和.f
,因此第一行( my_list |>
)是多余的。 它使my_list
被扔進map()
的...
部分,它什么都不起作用。
在rename_with()
的.fn
部分,如果使用公式樣式的 function,占位符.x
會發生沖突。 因此,您應該使用基本的 function 並設置不同的參數名稱。
purrr::map(.x = unique(names(my_list)),
.f = ~ my_list[names(my_list) == .x] |>
dplyr::bind_rows() |>
dplyr::rename_with(.cols = "x",
.fn = \(col) paste0("new_", .x)))
[[1]]
new_L1
1 1
2 2
3 3
4 1
5 2
6 3
[[2]]
new_L2
1 1
2 2
3 3
4 1
5 2
6 3
您也可以使用rename
,這樣您就不必擔心沖突。
|> dplyr::rename(!!paste0("new_", .x) := x)
我喜歡用來避免.x
沖突的另一種方法是對 map 使用匿名map
:
unique(names(my_list)) |>
# if you want a named list, use set_names
# purrr::set_names() |>
purrr::map(\(list_name) my_list[names(my_list) == list_name] |>
dplyr::bind_rows() |>
dplyr::rename_with(.cols = "x",
.fn = ~paste0("new_", list_name))
)
另一種選擇可能是:
imap(my_list,
~ .x %>%
rename_with(function(listnames) paste0("new_", .y), everything()))
$L1
new_L1
1 1
2 2
3 3
$L1
new_L1
1 1
2 2
3 3
$L2
new_L2
1 1
2 2
3 3
$L2
new_L2
1 1
2 2
3 3
如果您需要一個未命名的列表:
imap(my_list,
~ .x %>%
rename_with(function(listnames) paste0("new_", .y), everything())) %>%
unname()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.