2017-02-22 1 views
1

Was ist der Unterschied zwischen c() und list()? Ich lerne etwas webscraping und stieß auf einen unerwarteten Fehler. ich ein kleines Skript geschrieben Baseball Daten von ein paar Seiten auf ESPN Website zu kratzen:lapply, Unterschied zwischen c() und list()

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 
} 

wenn ich df <- lapply(Baseball.list, scrape) laufen erhalte ich:

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

Aber wenn ich Baseball.list <- list(Baseball, Baseball.2, Baseball.3, Baseball.4) laufen und dann lapply verwenden und Meine Funktion ist genau so, wie es ohne Probleme funktioniert! Ich überprüfte die Dokumentation für c() und sehe, dass: "Dies ist eine generische Funktion, die ihre Argumente kombiniert. Die Standardmethode kombiniert seine Argumente zu einem Vektor. Alle Argumente werden zu einem gemeinsamen Typ, der den Typ des zurückgegebenen Werts ist gezwungen , und alle Attribute außer Namen werden entfernt, "während die Dokumentation für list() besagt, dass ihre Objekte in eine Liste umgewandelt werden. Kann jemand erklären, warum die Verwendung von c() in diesem Fall dazu führt, dass lapply fehlschlägt? Ich verstehe die Dokumentation nicht.

+0

Die erste 'Baseball.list' (mit' c() ') dazu gezwungen wird zu 'as.list (Baseball.list)' in 'lapply', also vergleiche das mit deiner zweiten' Baseball.list'. –

+0

Ich sehe den Unterschied in der Ausgabe, aber verstehe immer noch nicht die Auswirkungen der Ausgabe. Teil meiner Verwirrung ist, dass in anderen Antworten (wie hier: http://stackoverflow.com/questions/28906601/harvest-rvest-multiple-html-pages-from-a-list-of-urls?rq=1) sie scheinen etwas ähnliches zu tun, aber c() funktioniert gut. Fehle ich etwas Grundlegendes? – ZLevine

Antwort

1

Genau wie die Dokumentation für c() sagt

„Alle Argumente sind mit einem gemeinsamen Typ umgewandelt, die der Typ des zurückgegebenen Wert, und alle Attribute außer Namen werden entfernt“

Die Liste enthält die Klassen der Dokumente, wie von xml2::read_html beabsichtigt. Wenn man sich die source code for xml2 schauen, sehen Sie, dass die generische Methode xml_find_all nur für Klassen von xml_missing definiert ist, xml_node und 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" 
Verwandte Themen