【问题标题】:purrr accumulate function strange outputpurrr 累积函数奇怪的输出
【发布时间】:2019-06-02 01:12:39
【问题描述】:

我猜这是两个问题的结合。

我试图理解purrr::accumulate 函数,但很难弄清楚.x.y 之间的相互作用。我一直在阅读purrr 小插图,但并没有解释太多。我没有编程背景,所以很多事情都在我的脑海中。

首先,为什么它们在同一个调用时会有不同的输出?唯一的区别是()paste 之后。

accumulate(letters[1:5], paste, sep = ".")
[1] "a"         "a.b"       "a.b.c"     "a.b.c.d"   "a.b.c.d.e"

accumulate(letters[1:5], paste(), sep = ".")
[1] "a" "a" "a" "a" "a"

第二,这里是怎么回事?

2:11 %>% accumulate(~ .x)
[1] 2 2 2 2 2 2 2 2 2 2

accumulate(1:5, `+`)
[1]  1  3  6 10 15

2:11 %>% accumulate(~ .y)
[1]  2  3  4  5  6  7  8  9 10 11

2:11 %>% accumulate(~ .x + .y)
[1]  2  5  9 14 20 27 35 44 54 65

.x 是累积值,但我猜它没有累积任何东西? 1:5cumsum 一样有意义。 .y 是列表中的元素。我将.y 解释为本质上是print 是否正确?

但是.x + .y 的第一个输出不是4吗?

欢迎提供一些见解。

【问题讨论】:

  • 在第一种情况下,您只使用.xcumsum(2:11)# [1] 2 5 9 14 20 27 35 44 54 65。所以,不清楚为什么不应该是一样的

标签: r purrr


【解决方案1】:

当有print语句时会更容易理解

2:11 %>% 
   accumulate(~ {
     print("---step----")
     print(paste0(".x: ", .x))
     print(paste0(".y: ", .y))
     print(.x + .y)
    })
#[1] "---step----"
#[1] ".x: 2"  # .init or first value of the vector (as `.init` not specified)
#[1] ".y: 3"  # second value
#[1] 5    # sum of .x + .y
#[1] "---step----"
#[1] ".x: 5"   # note .x gets updated with the sum
#[1] ".y: 4"   # .y gets the next element
#[1] 9
#[1] "---step----"
#[1] ".x: 9"   # similarly in all the below steps
#[1] ".y: 5"
#[1] 14
#[1] "---step----"
#[1] ".x: 14"
#[1] ".y: 6"
#[1] 20
#[1] "---step----"
#[1] ".x: 20"
#[1] ".y: 7"
#[1] 27
#[1] "---step----"
#[1] ".x: 27"
#[1] ".y: 8"
#[1] 35
#[1] "---step----"
#[1] ".x: 35"
#[1] ".y: 9"
#[1] 44
#[1] "---step----"
#[1] ".x: 44"
#[1] ".y: 10"
#[1] 54
#[1] "---step----"
#[1] ".x: 54"
#[1] ".y: 11"
#[1] 65
# [1]  2  5  9 14 20 27 35 44 54 65

这里,.x 是在每次迭代中更新的值,该值被传递到 .x + .y

本质上类似于

cumsum(2:11)
#[1]  2  5  9 14 20 27 35 44 54 65

当我们只传递.x 时,它是.init 值,即第一个没有更新的元素,因为.f 没有做任何事情

2:11 %>% 
    accumulate(~ print(.x))
#[1] 2
#[1] 2
#[1] 2
#[1] 2
#[1] 2
#[1] 2
#[1] 2
#[1] 2
#[1] 2
# [1] 2 2 2 2 2 2 2 2 2 2

现在,我们传递 .init 一个不同的值

2:11 %>%
    accumulate(~ print(.x), .init = 5)
#[1] 5
#[1] 5
#[1] 5
#[1] 5
#[1] 5
#[1] 5
#[1] 5
#[1] 5
#[1] 5
#[1] 5
#[1] 5 5 5 5 5 5 5 5 5 5 5

另外,前两次调用的不同之处在于传递参数的不同。在paste的第一种情况下,.x.y被隐式传递,而在第二种paste()中,它只是.x,即进入它

accumulate(letters[1:5], ~paste(.x, .y, sep = "."))
#[1] "a"         "a.b"       "a.b.c"     "a.b.c.d"   "a.b.c.d.e"
accumulate(letters[1:5], ~paste(.x,  sep = "."))
#[1] "a" "a" "a" "a" "a"

【讨论】:

  • 谢谢阿克伦。几个后续问题:在第一个示例中,运行代码会显示以2 开头的输出字符串,但迭代打印输出会跳过它并直接转到5。那里发生了什么事?其次,在最后一个示例中,为什么 .x.y 隐式传递时不带括号,而只传递 .x
  • @hmhensen 这是因为.x.init 的值作为第一个值,并且它没有得到更新,因为我们没有对其应用任何函数。
  • 第二个例子,你只需要检查paste# function (..., sep = " ", collapse = NULL)paste()# character(0)在第一个例子中,...可以接受任意数量的参数,它隐式接受.x和@ 987654350@,在第二种情况下,paste() 没有做任何事情,因为它在内部没有任何参数的情况下被调用,因此.x 被这样返回
  • @akrun,请查看并建议here
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-13
  • 2016-08-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多