Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
根据元素在R中的名称将多个函数应用于列表元素_R_List_Purrr - Fatal编程技术网

根据元素在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,这正是我想要的澄清-谢谢!