в общем, разница между c() и list()

В чем разница между c() и list()? Я изучаю веб-скрейпинг и столкнулся с неожиданной ошибкой. Я написал небольшой скрипт для сбора данных о бейсболе с нескольких страниц веб-сайта 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() говорится, что объекты вводятся в список. Может ли кто-нибудь объяснить, почему использование c() в этом случае приводит к сбою lapply? Я не понимаю документацию.


person ZLevine    schedule 22.02.2017    source источник
comment
Первый Baseball.listc()) приводится к as.list(Baseball.list) в lapply, поэтому сравните это со вторым Baseball.list.   -  person Rich Scriven    schedule 22.02.2017
comment
Я вижу разницу в выводе, но до сих пор не полностью понимаю последствия вывода. Часть моего замешательства заключается в том, что в других ответах (например, здесь: stackoverflow.com/questions/28906601/) они, похоже, делают что-то похожее, но c() работает нормально. Я пропустил что-то основное?   -  person ZLevine    schedule 22.02.2017


Ответы (1)


Как говорится в документации для c(),

«Все аргументы приводятся к общему типу, который является типом возвращаемого значения, и все атрибуты, кроме имен, удаляются»

В списке сохранены классы документов, как и было задумано xml2::read_html. Если вы посмотрите на исходный код для xml2, вы увидим, что общий метод xml_find_all определен только для классов xml_missing, xml_node и xml_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"
person Jean    schedule 22.02.2017