R - Composite functions vs piped functions in `purrr::map()`

三世轮回 提交于 2020-01-05 03:37:48

问题


I have the following list:

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"

I would like to figure out which data types are contained within each level 1 element. To do this, I can use the following pipeline:

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"

...which works as expected. But when I try to nest the call to unique inside unlist(), I get something different:

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"

Could someone please help me understand why these two approaches are not equivalent?


回答1:


It's easier to see what's happening if you use anonymous functions rather than the dot notation.

piped = map(my_list, ~map(., class) %>% unique %>% unlist) is the same as

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

The pipe then places the output of each step in the first position of each subsequent function, so it becomes

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

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

Which results is

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

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

can be written as

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

The two uses of x on both sides of the pipe is where things go weird. I think you were expecting the pipe to place the output of the inner map call in place of the x within the unique call, but the second x takes the output from the outer map function. Instead the pipe does its default action and places the output of the inner map call in the first position of the unlist function, like so

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

Which gives you

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


来源:https://stackoverflow.com/questions/57840592/r-composite-functions-vs-piped-functions-in-purrrmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!