r - 在purrr::map中相当于 `break`

标签 r dplyr purrr

假设我要运行一个循环,直到满足条件为止,此时将保存结果并退出循环:

library(tidyverse)

for (i in 1:5) {

  df <- iris %>% select(i) %>% head(2)

  if (names(df) == "Petal.Width") {
    out <- df
    break 

  }
}

out

如何在不评估每个i的情况下使用purr::map重写此代码?

进行以下操作即可得到所需的结果,但必须评估5次,而for循环仅进行3次:
fun <- function(x) {

  df <- iris %>% select(x) %>% head(2)

  if (names(df) == "Petal.Width") {
  return(df)
  }
}

map_df(1:5, fun)

最佳答案

没有对等的东西。实际上,使map(及类似函数)在可读性方面优于常规循环的一件事是,它们具有绝对可预测的行为:它们将对每个元素仅执行一次函数,无异常(exception)(除非,如果有,一个异常(exception):您可以通过stop提出条件以使执行短路,但这是极少建议的)。

相反,您的案例并不需要map,而是需要遵循purrr::keeppurrr::reduce的要求。

这样考虑:mapreduce等是抽象,对应于更通用的for循环的特定特殊情况。他们的目的是弄清正在处理哪种特殊情况。作为程序员,您的任务便是找到正确的抽象。

在您的特定情况下,我可能会使用dplyr完全重写该语句,因此很难提供“最佳” purrr解决方案:最佳解决方案是不使用purrr。也就是说,您可以按以下方式使用purrr::detect:

names(iris) %>%
    detect(`==`, 'Sepal.Width') %>%
    `[`(iris, .) %>%
    head(2)

或者
seq_along(iris) %>%
    detect(~ names(iris[.x]) == 'Sepal.Width') %>%
    `[`(iris, .) %>%
    head(2)

…但实际上,这里是dplyr供比较:
iris %>%
    select(Sepal.Width) %>%
    head(2)

关于r - 在purrr::map中相当于 `break`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54653415/

相关文章:

r - 使用 kable 在表格下方添加另一个标题

r - 在R中查找多维数组中的维索引

c - 在哪里可以了解有关 R 构建选项的更多信息?

r - 如何使用 dplyr 替换数据框中的字符?

重命名数据框列表中的所有列

r - 当列表中有向量时,如何将列表列转变为普通列,只留下最后一个值?

r - 根据分组变量计算百分比

r - R 中重叠/非重叠时间间隔的总和

r - 如何根据特定于该组的另一个变量为一组观察创建新变量

r - gls 模型的 `emmeans` 没有 't run inside ` map `