【问题标题】:row wise iteration with purrr does not work as expected使用 purrr 的逐行迭代无法按预期工作
【发布时间】:2019-11-05 16:24:12
【问题描述】:

我通常使用 for 循环来迭代对象。我最近从purrr 包中偶然发现了一个名为pmap() 的函数,它提供了另一种并行映射对象的方法。

我下面的例子不起作用,我不明白为什么。有谁知道,为什么在迭代数据帧时输出列表result 没有得到更新? for 循环会产生所需的输出,但会以可读性为代价。

# load packages
library(tidyverse)

# create small dataset
dat <- mtcars[1:3, 1:3] %>% 
  rownames_to_column()

# view dat
dat
#>         rowname  mpg cyl disp
#> 1     Mazda RX4 21.0   6  160
#> 2 Mazda RX4 Wag 21.0   6  160
#> 3    Datsun 710 22.8   4  108

# prepare output list
result <- list()

# map over dat and update object result
pwalk(dat, function(rowname, mpg, cyl, disp) {
  result[[rowname]] <- paste(mpg, cyl, disp)
})

# result did not get updated
result
#> list()

reprex package (v0.2.1) 于 2019-11-05 创建

【问题讨论】:

  • 您正在将一个函数传递给 pwalk 并修改该函数内的一个变量。您在函数内部修改的变量不存在于函数外部。
  • 这样的东西可能是一个更好的 tidyverse 替代方案。 set_names(pmap(dat %&gt;% select(-rowname), paste), dat$rowname)

标签: r iteration purrr


【解决方案1】:

正如@MrFlick 所提到的,您正试图在一个函数内为result 分配一个值,该函数有自己的环境。

您可以使用&lt;&lt;- 赋值运算符在全局环境中(函数外)修改result,并且几乎不会更改您的代码。但使用时要小心,不要修改你不打算修改的变量(甚至函数)。

来自 R 文档 (?`&lt;&lt;-`)

> 运算符通常只用在函数中,并导致通过父环境搜索被分配变量的现有定义。如果找到这样的变量(并且其绑定未锁定),则重新定义其值,否则在全局环境中进行赋值。

result <- list() # Defined in the global environment

pwalk(dat, function(rowname, mpg, cyl, disp) {
  result[[rowname]] <<- paste(mpg, cyl, disp)
  })

result

# Output
$`Mazda RX4`
[1] "21 6 160"

$`Mazda RX4 Wag`
[1] "21 6 160"

$`Datsun 710`
[1] "22.8 4 108"
})

【讨论】:

  • 很好的补充。但是使用&lt;&lt;-修改全局环境中的变量,一般来说是非常不好的做法。
  • 我同意。对于 99% 的情况,确实不建议这样做。您的解决方案(从pmap 返回列表并将其分配给result)是最佳实践。但知道一些“技巧”总不会有什么坏处。
  • 同意。&lt;&lt;- 在某些情况下很有用。
【解决方案2】:

正如@MrFlick 提到的,您正在修改函数环境中的变量。这就是您看不到预期结果的原因。

你可以试试:

# map over dat and update object result
result <- pmap(dat, function(rowname, mpg, cyl, disp) {
  paste(mpg, cyl, disp)
})

names(result) <- dat$rowname

result <- apply(dat, 1, function(x){
  paste(x[2],x[3],x[4])
})

names(result) <- dat$rowname

在基础 R 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 2015-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多