我觉得可能有tidyverse比for-loop. 从标准 tibble/dataframe 开始,创建一个列表,其中列表元素的名称是一列的唯一值 ( group_by?),列表元素是另一列的所有值。
my_data <- tibble(list_names = c("Ford", "Chevy", "Ford", "Dodge", "Dodge", "Ford"),\n list_values = c("Ranger", "Equinox", "F150", "Caravan", "Ram", "Explorer"))\n \n# A tibble: 6 \xc3\x97 2\n list_names list_values\n <chr> <chr> \n1 Ford Ranger \n2 Chevy Equinox \n3 Ford F150 \n4 Dodge Caravan \n5 Dodge Ram \n6 Ford Explorer\nRun Code Online (Sandbox Code Playgroud)\n这是所需的输出:
\n desired_output <- list(Ford = c("Ranger", "F150", "Explorer"),\n Chevy = c("Equinox"),\n Dodge = c("Caravan", "Ram"))\n\n$Ford\n[1] "Ranger" "F150" "Explorer"\n\n$Chevy\n[1] "Equinox"\n\n$Dodge\n[1] "Caravan" "Ram" \nRun Code Online (Sandbox Code Playgroud)\n它可以用 a 来完成,for-loop但我敢打赌有一个tidyverse函数可以使它更简单/更快,等等。
desired_output <- list()\n for(i in seq_along(my_data$list_names)) {\n entry <- my_data %>%\n filter(list_names == my_data$list_names[i]) %>%\n pull(list_values)\n desired_output[[my_data$list_names[i]]] <- entry\n }\nRun Code Online (Sandbox Code Playgroud)\n
group_modify这是使用and deframefrom的另一个选项(尽管更详细)tidyverse。
library(tidyverse)
my_data |>
group_by(list_names) |>
group_modify(\(x, ...) tibble(res = list(deframe(x)))) |>
deframe()
Run Code Online (Sandbox Code Playgroud)
或者另一种选择可能是使用summarise然后再次使用deframe:
my_data %>%
group_by(list_names) %>%
summarise(named_vec = list(list_values)) %>%
deframe()
Run Code Online (Sandbox Code Playgroud)
输出
$Chevy
[1] "Equinox"
$Dodge
[1] "Caravan" "Ram"
$Ford
[1] "Ranger" "F150" "Explorer"
Run Code Online (Sandbox Code Playgroud)
基准
我很想知道这里的答案中最快的是什么,并且split@akrun 看起来肯定是迄今为止最快的,其次是unstack.
bm <- microbenchmark::microbenchmark(
akrun_split = with(my_data, split(list_values,
factor(list_names, levels = unique(list_names)))),
akrun_unstack = unstack(my_data, list_values ~ list_names),
andrew_deframe1 = my_data |>
group_by(list_names) |>
group_modify(\(x, ...) tibble(res = list(deframe(x)))) |>
deframe(),
andrew_deframe2 = my_data %>%
group_by(list_names) %>%
summarise(named_vec = list(list_values)) %>%
deframe(),
paulsmith = my_data %>%
group_by(list_names) %>%
summarise(list_values = list(list_values)) %>%
{set_names(.$list_values, .$list_names)},
times=1000L
)
Run Code Online (Sandbox Code Playgroud)
我们可以用split
with(my_data, split(list_values,
factor(list_names, levels = unique(list_names))))
$Ford
[1] "Ranger" "F150" "Explorer"
$Chevy
[1] "Equinox"
$Dodge
[1] "Caravan" "Ram"
Run Code Online (Sandbox Code Playgroud)
或者与unstack
unstack(my_data, list_values ~ list_names)
$Chevy
[1] "Equinox"
$Dodge
[1] "Caravan" "Ram"
$Ford
[1] "Ranger" "F150" "Explorer"
Run Code Online (Sandbox Code Playgroud)