library(rvest)
urls <- c("https://www.r-bloggers.com", "https://www.stackoverflow.com")
docsFor <- list()
for(url in urls){
docsFor[[url]] <- read_html(url)
}
docsFor[[1]]
问题:我该如何用sapply / vapply做同样的事情?
使用sapply(urls, read_html)
不起作用,因此我选择了vapply
。如果我是正确的,我会需要externalptr(0)
之类的东西,但我不确定是否存在。
无法工作,因为没有externalptr()
?:
docs <- vapply(urls, read_html, FUN.VALUE = list(externalptr(0), externalptr(0)))
docs[[1]]
答案 0 :(得分:3)
简而言之,如果您要返回的是列表(这是您的情况),请使用lapply
而不是sapply
,后者是lapply
的包装,它返回一个{{ 1}},vector
或matrix
。
与array
相同的论点,因为正如注释中适当提到的,应仅将其用于简化对象。
因此,这种情况下最好的整洁解决方案是:
vapply
答案 1 :(得分:1)
本质上,应用族的每个成员默认情况下都会返回:
要充分将for
循环转换为apply-family函数,您必须首先询问什么是输入类型和所需的输出类型?由于read_html
返回XML类型的特殊类对象,因此它不能完全适合原子向量或矩阵。因此,lapply
将是最好的for
循环翻译。但是,它的同级可以处理对默认值或输入的各种更改:
施加
lapply(urls, read_html)
应用 (至少需要二维输入,例如矩阵或数组):
apply(matrix(urls), 1, read_html)
应用 (包装到lapply
,但需要simplify
参数)
sapply(urls, read_html, simplify=FALSE)
通过 (tapply
的面向对象包装)
by(urls, urls, function(x) read_html(as.character(x)))
mapply (需要SIMPLIFY
参数,该参数等效于包装器Map
)
mapply(read_html, urls, SIMPLIFY = FALSE)
Map(read_html, urls)
强行应用 (需要嵌套列表转换以及列表输出)
urls_list <- list(u1 = urls[1], u2 = urls[2])
rapply(urls_list, read_html, how="list")
以下功能由于默认值仅限于简化类型而无法使用,其中?
引用外部指针。
应用 (默认设置)
sapply(urls, read_html)
# https://www.r-bloggers.com https://www.stackoverflow.com
# node ? ?
# doc ? ?
vapply (通常只返回简化的对象)
vapply(urls, read_html, vector(mode="list", length=2))
# https://www.r-bloggers.com https://www.stackoverflow.com
# node ? ?
# doc ? ?
应用 (默认设置)
mapply(read_html, urls)
# https://www.r-bloggers.com https://www.stackoverflow.com
# node ? ?
# doc ? ?
应用
rapply(urls_list, read_html)
# $u1.node
# <pointer: 0x8638eb0>
# $u1.doc
# <pointer: 0x6f79b30>
# $u2.node
# <pointer: 0x9c98930>
# $u2.doc
# <pointer: 0x9cb19a0>
有关进一步的阅读,请参见下面的SO帖子:
Grouping functions (tapply, by, aggregate) and the *apply family