首页 > 解决方案 > 在 R 中定义一种新的 for 循环?

问题描述

我正在尝试研究如何for在 R 中定义自定义循环,或者是否有可能。

例子

有几件事会很高兴

是否可以在 R 中定义一种新的 for 循环(如果可以,如何定义),或者这是语言的固有限制,因此无法做到?

用例

这是一个随机示例,说明如何for_each_with_index简化繁琐的算术

假设我们要从网站上抓取第 36 到第 55 篇文章,并将输出分配到列表中的某个位置。这很好用

library(rvest)
library(dplyr)
articles <- vector(mode = "list", length = 20)
for(i in 36:55) {
  paste0("Scraping article ", i) %>% print
  articles[[i - 35]] <- read_html(paste0("http://afr.herokuapp.com/articles/", i)) %>% 
             html_nodes("p") %>% html_text %>% paste0(collapse="/n")
           }

但是我们看到了一些挑剔的算术(36:55i - 35),理论上可以通过for_each_with_index枚举对象的每个元素来抽象出来articles,如下所示:

# NOT ACTUAL R CODE

library(rvest)
library(dplyr)
articles <- vector(mode = "list", length = 20)
for_each_with_index(articles, i) {
  paste0("Scraping article ", i) %>% print
  articles[[i]] <- read_html(paste0("http://afr.herokuapp.com/articles/", i + 35)) %>% 
             html_nodes("p") %>% html_text %>% paste0(collapse="/n")
           }

通过使用for_each_with_index,我们避免了繁琐的算术。这个例子非常简单,但是当复杂度上升一些时,即当我们有各种条件、嵌套循环等时,事情变得更加复杂,这些看似微小的清晰度改进变得更加深刻

标签: r

解决方案


foreach包提供了一个模型

res = foreach(i = 1:3) %do% {
    sqrt(i)
}

这是使用 R%any%构造,它是一个可以由用户定义的中缀运算符,所以

`%with_index%` <- function(lhs, rhs) {
    ## implement ...
    Map(function(i) {
        list(i, rhs(lhs[[i]]))
    }, seq_along(lhs))
}

1:10 %with_index% sqrt

它还定义了foreach()设置右侧的功能。%do%必须以实现相对通用的方式编写,rhs这不是一项简单的任务。

实施for_each() %with_index% {}可能会非常有趣,而且很有教育意义。


推荐阅读