将函数应用于与数据框中的值匹配的列表元素
applying a function to elements of a list matched by values in a dataframe
我有一个名为 a、b 和 c 的数据框列表 (mylist)。我想对每个数据框的第一个变量 (var1) 的每个值应用一个简单的加法,对应于来自单独数据框 (shift_df) 的(匹配的)值,其中包含变量“id”(b , a, c) 和“移位”(2.1, 4.5, 6.6)。换句话说,我想得到一个列表,其中 mylist$b$var1 中的每个值都由 2.1 等添加
mylist <- list("a" = data.frame("var1" = c(1,2,3), "var2" = c(9,3,5)), "b" = data.frame("var1"= c(2,4,7), "var2" = c(5,1,5)), "c" = data.frame("var1" = c(8,5,6), "var2" = c(5,3,3)))
shift_df <- data.frame("id"=c("b", "a", "c"), "shift"=c(2.1, 4.2, 6.6))
我的想法是为此使用 lapply,但我无法正确应用与 shift_df$id 的匹配。感谢您的帮助!
lapply(mylist,function(x) {x[names(mylist)==shift_df[1]] + shift_df$shift[names(mylist)==shift_df[1]]})
一种data.table
方法。
首先,将列表连接在一起,使用列表元素的名称作为 id。
然后执行更新连接,将每个 id 的 shoft_df 值添加到 val1 和 val2.
最后,按 id.
将 data.table 拆分回列表
library(data.table)
split( rbindlist(mylist, idcol = "id")[setDT(shift_df),
`:=`(var1 = var1 + i.shift,
var2 = var2 + i.shift),
on = .(id)],
by = "id", keep.by = FALSE)
# $a
# var1 var2
# 1: 5.2 13.2
# 2: 6.2 7.2
# 3: 7.2 9.2
#
# $b
# var1 var2
# 1: 4.1 7.1
# 2: 6.1 3.1
# 3: 9.1 7.1
#
# $c
# var1 var2
# 1: 14.6 11.6
# 2: 11.6 9.6
# 3: 12.6 9.6
您可以在基数 R 中使用 Map
-
Map(`+`, mylist, shift_df$shift[match(names(mylist), shift_df$id)])
#$a
# var1 var2
#1 5.2 13.2
#2 6.2 7.2
#3 7.2 9.2
#$b
# var1 var2
#1 4.1 7.1
#2 6.1 3.1
#3 9.1 7.1
#$c
# var1 var2
#1 14.6 11.6
#2 11.6 9.6
#3 12.6 9.6
其中 match
returns 需要添加到列表中每个数据帧的 shift
值。
shift_df$shift[match(names(mylist), shift_df$id)]
#[1] 4.2 2.1 6.6
使用imap
library(purrr)
imap(mylist, ~ .x + with(shift_df, shift[id == .y]))
$a
var1 var2
1 5.2 13.2
2 6.2 7.2
3 7.2 9.2
$b
var1 var2
1 4.1 7.1
2 6.1 3.1
3 9.1 7.1
$c
var1 var2
1 14.6 11.6
2 11.6 9.6
3 12.6 9.6
或将 map2
与 split
一起使用
map2(mylist, split(shift_df$shift, shift_df$id), `+`)
或 pmap
pmap(shift_df, ~ mylist[[..1]] + ..2)
我有一个名为 a、b 和 c 的数据框列表 (mylist)。我想对每个数据框的第一个变量 (var1) 的每个值应用一个简单的加法,对应于来自单独数据框 (shift_df) 的(匹配的)值,其中包含变量“id”(b , a, c) 和“移位”(2.1, 4.5, 6.6)。换句话说,我想得到一个列表,其中 mylist$b$var1 中的每个值都由 2.1 等添加
mylist <- list("a" = data.frame("var1" = c(1,2,3), "var2" = c(9,3,5)), "b" = data.frame("var1"= c(2,4,7), "var2" = c(5,1,5)), "c" = data.frame("var1" = c(8,5,6), "var2" = c(5,3,3)))
shift_df <- data.frame("id"=c("b", "a", "c"), "shift"=c(2.1, 4.2, 6.6))
我的想法是为此使用 lapply,但我无法正确应用与 shift_df$id 的匹配。感谢您的帮助!
lapply(mylist,function(x) {x[names(mylist)==shift_df[1]] + shift_df$shift[names(mylist)==shift_df[1]]})
一种data.table
方法。
首先,将列表连接在一起,使用列表元素的名称作为 id。
然后执行更新连接,将每个 id 的 shoft_df 值添加到 val1 和 val2.
最后,按 id.
library(data.table)
split( rbindlist(mylist, idcol = "id")[setDT(shift_df),
`:=`(var1 = var1 + i.shift,
var2 = var2 + i.shift),
on = .(id)],
by = "id", keep.by = FALSE)
# $a
# var1 var2
# 1: 5.2 13.2
# 2: 6.2 7.2
# 3: 7.2 9.2
#
# $b
# var1 var2
# 1: 4.1 7.1
# 2: 6.1 3.1
# 3: 9.1 7.1
#
# $c
# var1 var2
# 1: 14.6 11.6
# 2: 11.6 9.6
# 3: 12.6 9.6
您可以在基数 R 中使用 Map
-
Map(`+`, mylist, shift_df$shift[match(names(mylist), shift_df$id)])
#$a
# var1 var2
#1 5.2 13.2
#2 6.2 7.2
#3 7.2 9.2
#$b
# var1 var2
#1 4.1 7.1
#2 6.1 3.1
#3 9.1 7.1
#$c
# var1 var2
#1 14.6 11.6
#2 11.6 9.6
#3 12.6 9.6
其中 match
returns 需要添加到列表中每个数据帧的 shift
值。
shift_df$shift[match(names(mylist), shift_df$id)]
#[1] 4.2 2.1 6.6
使用imap
library(purrr)
imap(mylist, ~ .x + with(shift_df, shift[id == .y]))
$a
var1 var2
1 5.2 13.2
2 6.2 7.2
3 7.2 9.2
$b
var1 var2
1 4.1 7.1
2 6.1 3.1
3 9.1 7.1
$c
var1 var2
1 14.6 11.6
2 11.6 9.6
3 12.6 9.6
或将 map2
与 split
map2(mylist, split(shift_df$shift, shift_df$id), `+`)
或 pmap
pmap(shift_df, ~ mylist[[..1]] + ..2)