使用 R 中的 map() 将列表元素中的列乘以向量以创建新列
Multiply a column in a list element by a vector using map() in R to create new columns
我有一个包含多个元素的列表(13 个元素,每个元素的维度不同,但列名相同),例如:
tbl1 <- tibble(Code = c(1,2,3,4),
Column1 = c(10,11,12,13),
Column2 = c(14,15,16,17))
tbl2 <- tibble(Code = c(5,6,7,8),
Column1 = c(14,15,16,17),
Column2 = c(18,19,20,21))
my_list <- list(Element1 = tbl1, Element2 = tbl2)
vector <- c(0.5, 0.6, 0.7, 0.8)
我想将每个列表元素的 Column2 乘以每个向量元素,并将结果列绑定到数据框,如下所示:
my_list %>%
map(.f = function(x) x %>%
mutate(!!paste0("Column_", vector[1]) := pmap_dbl(list(Column2, vector[1]), prod),
!!paste0("Column_", vector[2]) := pmap_dbl(list(Column2, vector[2]), prod),
!!paste0("Column_", vector[3]) := pmap_dbl(list(Column2, vector[3]), prod),
!!paste0("Column_", vector[4]) := pmap_dbl(list(Column2, vector[4]), prod)))
$Element1
# A tibble: 4 x 7
Code Column1 Column2 Column_0.5 Column_0.6 Column_0.7 Column_0.8
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 10 14 7 8.4 9.8 11.2
2 2 11 15 7.5 9 10.5 12
3 3 12 16 8 9.6 11.2 12.8
4 4 13 17 8.5 10.2 11.9 13.6
$Element2
# A tibble: 4 x 7
Code Column1 Column2 Column_0.5 Column_0.6 Column_0.7 Column_0.8
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 5 14 18 9 10.8 12.6 14.4
2 6 15 19 9.5 11.4 13.3 15.2
3 7 16 20 10 12 14 16
4 8 17 21 10.5 12.6 14.7 16.8
但我无法弄清楚如何通过向量对其进行迭代...如何将 mutate(!!paste0("Column_", vector[x]) := pmap_dbl(list(Column2, vector[x]), prod)
更改为 map() 以便它尽可能通用并且可以与向量一起使用任何长度?
期待您的想法!
谢谢
这是一种策略。基本上你使用 map_dfc
将向量变成一堆列。
map(my_list, function(x) {
bind_cols(x, map_dfc(set_names(vector, paste0("Column_", vector)), ~x$Column2*.x))
})
因为我们有一个嵌套映射,所以我为接收每个 data.frame 的外部函数使用了一个显式函数。这将有助于区分 x
(data.frame)和 .x
(向量的值)。我们使用 set_names
以便 map_dfc
将使用它们作为它创建的新列的名称。实际的乘法不需要映射,因为乘法在 R 中被矢量化了。
基础 R 尝试 -
cols <- paste0('Column_', vector)
lapply(my_list, function(x) {
x[cols] <- lapply(vector, `*`, x$Column2)
x
})
#$Element1
# A tibble: 4 x 7
# Code Column1 Column2 Column_0.5 Column_0.6 Column_0.7 Column_0.8
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 1 10 14 7 8.4 9.8 11.2
#2 2 11 15 7.5 9 10.5 12
#3 3 12 16 8 9.6 11.2 12.8
#4 4 13 17 8.5 10.2 11.9 13.6
#$Element2
# A tibble: 4 x 7
# Code Column1 Column2 Column_0.5 Column_0.6 Column_0.7 Column_0.8
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 5 14 18 9 10.8 12.6 14.4
#2 6 15 19 9.5 11.4 13.3 15.2
#3 7 16 20 10 12 14 16
#4 8 17 21 10.5 12.6 14.7 16.8
我有一个包含多个元素的列表(13 个元素,每个元素的维度不同,但列名相同),例如:
tbl1 <- tibble(Code = c(1,2,3,4),
Column1 = c(10,11,12,13),
Column2 = c(14,15,16,17))
tbl2 <- tibble(Code = c(5,6,7,8),
Column1 = c(14,15,16,17),
Column2 = c(18,19,20,21))
my_list <- list(Element1 = tbl1, Element2 = tbl2)
vector <- c(0.5, 0.6, 0.7, 0.8)
我想将每个列表元素的 Column2 乘以每个向量元素,并将结果列绑定到数据框,如下所示:
my_list %>%
map(.f = function(x) x %>%
mutate(!!paste0("Column_", vector[1]) := pmap_dbl(list(Column2, vector[1]), prod),
!!paste0("Column_", vector[2]) := pmap_dbl(list(Column2, vector[2]), prod),
!!paste0("Column_", vector[3]) := pmap_dbl(list(Column2, vector[3]), prod),
!!paste0("Column_", vector[4]) := pmap_dbl(list(Column2, vector[4]), prod)))
$Element1
# A tibble: 4 x 7
Code Column1 Column2 Column_0.5 Column_0.6 Column_0.7 Column_0.8
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 10 14 7 8.4 9.8 11.2
2 2 11 15 7.5 9 10.5 12
3 3 12 16 8 9.6 11.2 12.8
4 4 13 17 8.5 10.2 11.9 13.6
$Element2
# A tibble: 4 x 7
Code Column1 Column2 Column_0.5 Column_0.6 Column_0.7 Column_0.8
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 5 14 18 9 10.8 12.6 14.4
2 6 15 19 9.5 11.4 13.3 15.2
3 7 16 20 10 12 14 16
4 8 17 21 10.5 12.6 14.7 16.8
但我无法弄清楚如何通过向量对其进行迭代...如何将 mutate(!!paste0("Column_", vector[x]) := pmap_dbl(list(Column2, vector[x]), prod)
更改为 map() 以便它尽可能通用并且可以与向量一起使用任何长度?
期待您的想法!
谢谢
这是一种策略。基本上你使用 map_dfc
将向量变成一堆列。
map(my_list, function(x) {
bind_cols(x, map_dfc(set_names(vector, paste0("Column_", vector)), ~x$Column2*.x))
})
因为我们有一个嵌套映射,所以我为接收每个 data.frame 的外部函数使用了一个显式函数。这将有助于区分 x
(data.frame)和 .x
(向量的值)。我们使用 set_names
以便 map_dfc
将使用它们作为它创建的新列的名称。实际的乘法不需要映射,因为乘法在 R 中被矢量化了。
基础 R 尝试 -
cols <- paste0('Column_', vector)
lapply(my_list, function(x) {
x[cols] <- lapply(vector, `*`, x$Column2)
x
})
#$Element1
# A tibble: 4 x 7
# Code Column1 Column2 Column_0.5 Column_0.6 Column_0.7 Column_0.8
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 1 10 14 7 8.4 9.8 11.2
#2 2 11 15 7.5 9 10.5 12
#3 3 12 16 8 9.6 11.2 12.8
#4 4 13 17 8.5 10.2 11.9 13.6
#$Element2
# A tibble: 4 x 7
# Code Column1 Column2 Column_0.5 Column_0.6 Column_0.7 Column_0.8
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 5 14 18 9 10.8 12.6 14.4
#2 6 15 19 9.5 11.4 13.3 15.2
#3 7 16 20 10 12 14 16
#4 8 17 21 10.5 12.6 14.7 16.8