【问题标题】:R - Composite functions vs piped functions in `purrr::map()`R - `purrr::map()` 中的复合函数与管道函数
【发布时间】:2019-09-08 09:12:56
【问题描述】:

我有以下列表:

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"

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

【问题讨论】:

  • 我认为点的两种用法在不同的范围内,导致了意想不到的行为,但不能完全梳理出来。
  • 感谢您的意见@pgcudahy,我尝试使用unique(.x) 代替unique(.),但得到了相同的结果。

标签: r data-manipulation purrr


【解决方案1】:

如果您使用匿名函数而不是点符号,则更容易看到发生了什么。

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"

【讨论】:

  • 感谢您如此彻底地解释@pgcudahy!以这种方式编写管道确实有助于我的理解。这与为什么使用.x 代替第二个. 不起作用的原因相同吗?我不确定 map(., ~map(., class) %>% unlist(unique(.x))) 的计算结果是什么 (map(my_list, function(x) map(x, class) %>% unlist(unique(.x)))?) 以及 .x 的范围。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-03
  • 1970-01-01
  • 2019-06-08
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多