【问题标题】:Return value of for() loop as if it were a function in Rfor() 循环的返回值,就像它是 R 中的函数一样
【发布时间】:2019-06-26 08:00:11
【问题描述】:

我在 R 脚本中有这个 for 循环:

url <- "https://example.com"
page <- html_session(url, config(ssl_verifypeer = FALSE))

links <- page %>% 
  html_nodes("td") %>% 
  html_nodes("tr") %>%
  html_nodes("a") %>% 
  html_attr("href")

base_names <- page %>%
  html_nodes("td") %>% 
  html_nodes("tr") %>%
  html_nodes("a") %>% 
  html_attr("href") %>%
  basename()

for(i in 1:length(links)) {

  site <- html_session(URLencode(
    paste0("https://example.com", links[i])),
    config(ssl_verifypeer = FALSE))

  writeBin(site$response$content, base_names[i])
} 

这会循环链接,并将文本文件下载到我的工作目录。我想知道是否可以将return 放在某个地方,以便它返回文档。

原因是,我正在 NiFi 中执行我的脚本(使用 ExecuteProcess),它并没有将我的抓取文件发送到下线。相反,它只显示了我的 R 脚本的头部。我假设您会将for 循环包装在fun &lt;- function(x) {} 中,但我不确定如何将x 集成到已经工作的刮板中。

我需要它来顺流返回文档,而不仅仅是这个:

处理器配置:

即使你不熟悉 NiFi,它也会对 R 部分有很大帮助!谢谢

【问题讨论】:

  • 您可以使用out &lt;- Map(function(link, bn) { site &lt;- ...link...; writeBin(..., bn); return(site$response$content); }, links, base_names),而不是for 循环。 (顺便说一句:您缺少base_names 的定义。)
  • 糟糕,修复了命名错误@r2evans,我的错。 bn 在您的评论中指的是什么?
  • bn 是我在匿名函数中用作第二个参数的任意名称; Maplinksbase_names 的成对元素“压缩”在一起,将第一个元素分别分配给函数内的linkbn。如果lapply(links, function(link) {...}) 仅适用于链接,则Map(function(link, bn) {...}, links, base_names) 与两者等效。
  • 所以Map(myfunc, links, base_names) 展开到myfunc(links[1], base_names[1]),然后myfunc(links[2], base_names[2])Map 总是返回list,而mapply 可能 返回一个向量(类似于lapply-vs-sapply)。
  • 我正在尝试修改您的第一条评论(感谢它的逻辑,顺便说一句)。我假设我应该摆脱分号?为愚蠢的问题道歉。不像我应该熟悉的那样熟悉Map。很难用评论格式来描绘。如果您想提供答案,那将很有帮助

标签: r for-loop apache-nifi


【解决方案1】:

如果您的意图是(1)保存输出(使用writeBin(2)返回值(使用list),那么试试这个:

out <- Map(function(ln, bn) {
  site <- html_session(URLencode(
    paste0("https://example.com", ln)),
    config(ssl_verifypeer = FALSE))
  writeBin(site$response$content, bn)
  site$response$content
}, links, base_names)

Map 的使用将各个元素“压缩”在一起。对于基本情况,以下是相同的:

Map(myfunc, list1)
lapply(list1, myfunc)

但是如果你想使用多个列表中的相同索引元素,你可以做一个

lapply(seq_len(length(list1)), function(i) myfunc(list1[i], list2[i], list3[i]))
Map(myfunc, list1, list2, list3)

展开Map 会有效地导致:

myfunc(list1[1], list2[1], list3[1])
myfunc(list1[2], list2[2], list3[2])
# ...

lapplyMap 之间的最大区别在于lapply 只能接受一个向量,而Map 接受一个或更多(实际上是无限的),将它们压缩在一起。所有使用的列表的长度必须相同或长度为 1(已回收),所以这样做是合法的

Map(myfunc, list1, list2, "constant string")

注意:Map-versus-mapply 类似于lapply-vs-sapply。对于两者,第一个 always 返回一个 list 对象,而第二个将返回一个 vector IFF 每个返回值的长度/尺寸相同,否则它也将返回一个 list .

【讨论】:

  • 在这种情况下,在最后一个 site$response$content 之前没有 return?否则,我认为这是一个很好的展示使用什么而不是循环。我在哪里可以给你送啤酒?
  • return 隐含在此处...如果您愿意,请使用 return(site$response$content)
  • 明白了。 (我真的会给你送啤酒钱,谢谢你的耐心)
  • 返回值是否与writeBin创建的文件不同?
  • 实际上想通了......它正在将文件转储到容器内的随机 NiFi 目录中(只能通过终端查看)。我所做的并不理想......但客户想要......所以你知道
猜你喜欢
  • 2021-01-06
  • 1970-01-01
  • 2015-08-08
  • 2021-08-14
  • 1970-01-01
  • 2019-05-27
  • 2019-10-19
  • 2015-08-08
  • 2011-11-25
相关资源
最近更新 更多