R-`purrr :: map()`中的复合函数与管道函数

时间:2019-09-08 09:12:56

标签: r data-manipulation purrr

我有以下列表:

my_list = list(alpha = list('hi'), 
               beta = list(1:4, 'how'), 
               gamma = list(TRUE, FALSE, 'are'))
str(my_list)

List of 3
 $ alpha:List of 1
  ..$ : chr "hi"
 $ beta :List of 2
  ..$ : int [1:4] 1 2 3 4
  ..$ : chr "how"
 $ gamma:List of 3
  ..$ : logi TRUE
  ..$ : logi FALSE
  ..$ : chr "are"

我想弄清楚每个1级元素中包含哪些数据类型。为此,我可以使用以下管道:

piped = map(my_list, ~map(., class) %>% unique %>% unlist)
str(piped)
List of 3
 $ alpha: chr "character"
 $ beta : chr [1:2] "integer" "character"
 $ gamma: chr [1:2] "logical" "character"

...按预期工作。但是,当我尝试将对unique的调用嵌套在unlist()中时,我得到了一些不同的东西:

composite = map(my_list, ~map(., class) %>% unlist(unique(.)))
str(composite)
List of 3
 $ alpha: chr "character"
 $ beta : chr [1:2] "integer" "character"
 $ gamma: chr [1:3] "logical" "logical" "character"

有人可以帮我理解为什么这两种方法不等效吗?

1 个答案:

答案 0 :(得分:3)

如果您使用匿名函数而不是点符号,则更容易看到正在发生的情况。

piped = map(my_list, ~map(., class) %>% unique %>% unlist)

相同

piped = map(my_list, function (x) map(x, class) %>% unique %>% unlist)

然后管道将每个步骤的输出放置在每个后续函数的第一个位置,因此它变为

piped = map(my_list, function (x) unique(map(x, class)) %>% unlist),然后

piped = map(my_list, function (x) unlist(unique(map(x, class))))

结果是

str(piped)
List of 3
 $ alpha: chr "character"
 $ beta : chr [1:2] "integer" "character"
 $ gamma: chr [1:2] "logical" "character"

类似composite = map(my_list, ~map(., class) %>% unlist(unique(.)))

可以写为

composite = map(my_list, function(x) map(x, class) %>% unlist(unique(x)))

在管道两边使用x的两种用法很奇怪。我认为您期望管道将内部映射调用的输出放置在unique调用中的x处,但是第二个x从外部映射函数获取输出。相反,管道会执行其默认操作,并将内部映射调用的输出放置在unlist函数的第一位置,就像这样

composite = map(my_list, function(x) unlist(map(x, class),unique(x)))

哪个给你

str(composite)
List of 3
 $ alpha: chr "character"
 $ beta : chr [1:2] "integer" "character"
 $ gamma: chr [1:3] "logical" "logical" "character"