lapply,c()和list()之间的区别

时间:2017-02-22 03:08:12

标签: r rvest

c()和list()有什么区别? 我正在学习一些webscraping并遇到意外错误。 我写了一个小脚本,从ESPN网站的几页上抓取棒球数据:

library(magrittr)
library(rvest)

Baseball <- read_html("http://www.espn.com/mlb/stats/batting/_/qualified/true")
Baseball.2 <- read_html("http://www.espn.com/mlb/stats/batting/_/count/41/qualified/true")
Baseball.3 <- read_html("http://www.espn.com/mlb/stats/batting/_/count/81/qualified/true")
Baseball.4 <- read_html("http://www.espn.com/mlb/stats/batting/_/count/121/qualified/true")
Baseball.list <- c(Baseball, Baseball.2, Baseball.3, Baseball.4)


scrape <- function(html) {
  temp.df <- data.frame(1:length(html %>%
                                   html_nodes(paste0("td:nth-child(2)")) %>%
                                   html_text()))
  for (i in 2:19) {
  temp.df[i - 1] <- 
    html %>%
    html_nodes(paste0("td:nth-child(", i, ")")) %>%
    html_text()
  }
  temp.df
}

当我运行df <- lapply(Baseball.list, scrape)时,我得到:

Error in UseMethod("xml_find_all") : 
  no applicable method for 'xml_find_all' applied to an object of class "externalptr" 

但是,如果我运行Baseball.list <- list(Baseball, Baseball.2, Baseball.3, Baseball.4)然后使用lapply和我的函数完全相同的方式它没有问题!我检查了c()的文档并看到:  “这是一个结合其论点的通用函数。 默认方法结合其参数以形成向量。所有参数都被强制转换为一个公共类型,它是返回值的类型,除了名称之外的所有属性都被删除,“而list()的文档说它将对象强制转换为列表。有人可以解释为什么使用{{ 1}}在这个例子中导致lapply失败?我不理解文档。

1 个答案:

答案 0 :(得分:1)

正如c()的文档所说的那样,

  

“所有参数都被强制转换为公共类型,这是返回值的类型,除名称之外的所有属性都被删除”

该列表保留了xml2::read_html所预期的文档类。如果您查看source code for xml2,您会看到通用方法xml_find_all仅针对xml_missingxml_nodexml_nodeset

> class(read_html("<html><title>Hi<title></html>"))
[1] "xml_document" "xml_node"    
> a = read_html("<html><title>Hi<title></html>")
> b = read_html("<html><title>Hi<title></html>")
> c = read_html("<html><title>Hi<title></html>")
> lapply(c(a,b,c), class)
$node
[1] "externalptr"

$doc
[1] "externalptr"

$node
[1] "externalptr"

$doc
[1] "externalptr"

$node
[1] "externalptr"

$doc
[1] "externalptr"

> lapply(list(a,b,c), class)
[[1]]
[1] "xml_document" "xml_node"    

[[2]]
[1] "xml_document" "xml_node"    

[[3]]
[1] "xml_document" "xml_node"