我有一个包含三列的数据框架,其中两列可以包含数值或列表。我想添加额外的列,其中包含这两列中的每列的最小/最大值。例如,我的数据帧可能看起来像;
df <- structure(list(ID = c(1L, 2L, 3L), A = structure(list(
5, c(0.5, 0.6), 2), names = c("", "", "")), B = structure(list(
c(0.2, 0.3), 6, c(0.1, 0.1)), names = c("", "", ""))), row.names = c(NA,
3L), class = "data.frame")
我想改变它来添加列;
<表类>ID B min_A max_A min_B max_B tbody><<tr>1 5 0.2, 0.3 5 5 0.2 0.3 20.5, 0.6 6 0.5 0.6 6 6 3 2 0.1, 0.1 2 2 0.1 0.1 表类>
使用map
和across
library(purrr)
library(dplyr)
df %>%
mutate(across(A:B, ~map_dbl(.x, min), .names = 'min_{.col}'),
across(A:B, ~ map_dbl(.x, max), .names = 'max_{.col}'))
与产出
ID A B min_A min_B max_A max_B
1 1 5 0.2, 0.3 5.0 0.2 5.0 0.3
2 2 0.5, 0.6 6 0.5 6.0 0.6 6.0
3 3 2 0.1, 0.1 2.0 0.1 2.0 0.1
您应该可以通过添加rowwise()
得到答案。我也在我的回答中使用了across()
,但这部分不是100%必要的,只是更有效率一点:
library(tidyverse)
df %>%
rowwise() %>%
mutate(across(A:B, function(x) min(unlist(x)), .names = "min_{.col}")) %>%
mutate(across(A:B, function(x) max(unlist(x)), .names = "max_{.col}"))
# A tibble: 3 × 7
# Rowwise:
ID A B min_A min_B max_A max_B
<dbl> <list> <list> <dbl> <dbl> <dbl> <dbl>
1 1 <dbl [1]> <dbl [2]> 5 0.2 5 0.3
2 2 <dbl [2]> <dbl [1]> 0.5 6 0.6 6
3 3 <dbl [1]> <dbl [2]> 2 0.1 2 0.1
带循环的Base R:
cols <- c("A", "B")
for(col in cols){
df[,paste0("min_", col)] <- sapply(df[,col], function(x) min(unlist(x)))
df[,paste0("max_", col)] <- sapply(df[,col], function(x) max(unlist(x)))
}