根据元素在R中的名称将多个函数应用于列表元素
考虑以下列表结构:根据元素在R中的名称将多个函数应用于列表元素,r,list,purrr,R,List,Purrr,考虑以下列表结构: AA <- data.frame("variable1" = c("a", "b"), "variable2" = 1:2) BB <- data.frame("variable1" = c("a", "b"), "variable2" = 3:4) my_list <- list(AA=AA, BB
AA <- data.frame("variable1" = c("a", "b"), "variable2" = 1:2)
BB <- data.frame("variable1" = c("a", "b"), "variable2" = 3:4)
my_list <- list(AA=AA, BB=BB)
> my_list
$AA
variable1 variable2
1 a 1
2 b 2
$BB
variable1 variable2
1 a 3
2 b 4
我的目标是将AA\u recoding
函数应用于AA
列表元素,将BB\u recoding
函数应用于BB
,以实现如下输出:
$AA
variable1 variable2
1 hello 1
2 b 2
$BB
variable1 variable2
1 goodbye 3
2 b 4
这似乎是purr
函数(如map
/imap
)的工作,但我看不到一种方法可以通过名称将我的函数专门定向到它们各自的列表元素。我尝试使用glue
(和paste0
)时遇到以下错误:
> my_list %>% imap(~.x %>% glue("{.y}_recoding"))
Error: All unnamed arguments must be length 1
> my_list %>% map(~.x %>% paste0(.y,"_recoding"))
Error in paste0(., .y, "_recoding") :
the ... list contains fewer than 2 elements
我是否以正确的方式从根本上解决了这个问题?我们可以使用
map2
,通过将函数包装在列表中,将相应的函数应用于列表的元素
library(purrr)
map2(my_list, list(AA_recoding, BB_recoding), ~ .y(.x))
#$AA
# variable1 variable2
#1 hello 1
#2 b 2
#$BB
# variable1 variable2
#1 goodbye 3
#2 b 4
请注意,上面的列表
(列表(AA\u recoding,BB\u recoding)
)是按照与“我的列表”中相同的名称顺序手动创建的,但也可以通过粘贴/stru c
和mget
(返回值)自动创建
或者,如果我们想从列表的名称
中从imap
中获取函数值,可以使用match.fun包装获取值
my_list %>%
imap(~ match.fun(str_c(.y, '_recoding'))(.x))
或者使用get
my_list %>%
imap(~ get(str_c(.y, '_recoding'))(.x))
我们可以使用map2
,通过将函数包装在列表中,将相应的函数应用于列表的元素
library(purrr)
map2(my_list, list(AA_recoding, BB_recoding), ~ .y(.x))
#$AA
# variable1 variable2
#1 hello 1
#2 b 2
#$BB
# variable1 variable2
#1 goodbye 3
#2 b 4
请注意,上面的列表
(列表(AA\u recoding,BB\u recoding)
)是按照与“我的列表”中相同的名称顺序手动创建的,但也可以通过粘贴/stru c
和mget
(返回值)自动创建
或者,如果我们想从列表的名称
中从imap
中获取函数值,可以使用match.fun包装获取值
my_list %>%
imap(~ match.fun(str_c(.y, '_recoding'))(.x))
或者使用get
my_list %>%
imap(~ get(str_c(.y, '_recoding'))(.x))
根据条件的多少,您可以将函数组合成一个记录函数,然后使用lappy
根据列表中项目的名称有条件地应用它
这有点老套,因为lapply不保留单个列表的名称。因此,在每个数据帧中创建一个与列表名称对应的列,然后使用lappy
应用新的组合函数
new_list <- my_list
list_names <- c("AA", "BB")
for(i in 1:length(my_list)){
new_list[[i]]$name <- list_names[[i]]
}
> new_list # Looks like this
$AA
variable1 variable2 name
1 a 1 AA
2 b 2 AA
$BB
variable1 variable2 name
1 a 3 BB
2 b 4 BB
# Combined function
AA_BB_recoding <- function(x){
x$variable1 <- ifelse(x$name == "AA", x$variable1 %>%
recode("a" = "hello"), x$variable1 %>%
recode("a" = "goodbye"))
return(x)
}
> lapply(new_list, function(f) AA_BB_recoding(f))
# returns
$AA
variable1 variable2 name
1 hello 1 AA
2 b 2 AA
$BB
variable1 variable2 name
1 goodbye 3 BB
2 b 4 BB
new\u list根据您有多少条件,您可以将函数组合成一个记录函数,然后使用lappy
根据列表中项目的名称有条件地应用它
这有点老套,因为lapply不保留单个列表的名称。因此,在每个数据帧中创建一个与列表名称对应的列,然后使用lappy
应用新的组合函数
new_list <- my_list
list_names <- c("AA", "BB")
for(i in 1:length(my_list)){
new_list[[i]]$name <- list_names[[i]]
}
> new_list # Looks like this
$AA
variable1 variable2 name
1 a 1 AA
2 b 2 AA
$BB
variable1 variable2 name
1 a 3 BB
2 b 4 BB
# Combined function
AA_BB_recoding <- function(x){
x$variable1 <- ifelse(x$name == "AA", x$variable1 %>%
recode("a" = "hello"), x$variable1 %>%
recode("a" = "goodbye"))
return(x)
}
> lapply(new_list, function(f) AA_BB_recoding(f))
# returns
$AA
variable1 variable2 name
1 hello 1 AA
2 b 2 AA
$BB
variable1 variable2 name
1 goodbye 3 BB
2 b 4 BB
新列表facepalm。。。谢谢@akrun。如果您不介意的话,可以解释一下map2
如何知道没有AA
/BB
索引的相应函数吗?这是列表的顺序吗?@Scott我创建的列表(AA_recoding,BB_recoding)
与我的列表的名称顺序相同。如果您想实现自动化,可以尝试map2(我的列表,mget(str_c(名称(我的列表),''u recoding')),~.y(.x))
Perfect,这正是我想要的澄清-谢谢!脸掌。。。谢谢@akrun。如果您不介意的话,可以解释一下map2
如何知道没有AA
/BB
索引的相应函数吗?这是列表的顺序吗?@Scott我创建的列表(AA_recoding,BB_recoding)
与我的列表的名称顺序相同。如果您想实现自动化,可以尝试map2(我的列表,mget(str_c(名称(我的列表),''u recoding')),~.y(.x))
Perfect,这正是我想要的澄清-谢谢!