2015-04-10 7 views
8

Na powierzchni obaj wydają się robić to samo. Wygląda jednak na to, że ta ostatnia wersja jest silniejsza.Jaka jest różnica między as.character() i (, "character") w R

jako przykład pod uwagę:

library(rvest) 

temp <- html("http://www.example.com/") 
temp <- temp %>% html_node("div p") 

str(temp) 
#Classes 'XMLInternalElementNode', 'XMLInternalNode', 'XMLAbstractNode' <externalptr> 

as.character(temp) 
#Error in as.vector(x, "character") 
# cannot coerce type 'externalptr' to vector of type 'character' 

Zważywszy as(temp, "character") daje

#[1] "<p>This domain is established to be used for illustrative examples in documents. You may use this\n domain in examples without prior coordination or asking for permission.</p>" 

Odpowiedz

9

as.character() jest S3 ogólny, natomiast as() jest funkcją zdefiniowane w pakiecie metody leków generycznych i metody S4.

Autor klasie S3 nie ma powodu, aby napisać metodę przymus S4, więc dla intance

> as.data.frame(matrix(integer())) 
[1] V1 
<0 rows> (or 0-length row.names) 

ale

> as(matrix(integer()), "data.frame") 
Error in as(matrix(), "data.frame") : 
    no method or default for coercing "matrix" to "data.frame" 

Dla klas S4, jeden (tj deweloper pakiet) potrafi (i naprawdę powinien) pisać zarówno metody S3, jak i S4 dla przymusu poszczególnych klas; wspólny paradygmat jest

as.character.MyClass <- function(x, ...) {} 
setAs("MyClass", "character", 
     function(from) as.character.MyClass(from)) 

W przykładzie autor (XML) dostarczyła setas funkcji bez ekwiwalentu S3, więc masz specjalnego traktowania przy użyciu as(), ale domyślne (czyli błąd) podczas korzystania as.character().

Nie ma ogólnej zasady, która jest "mocniejsza"; nie byłoby wcale zaskakujące, aby znaleźć przykłady nawet w bazie R i pakiecie metod, gdzie as.X i as (, "X") zachowują się inaczej, nawet w logicznie niespójny sposób.

W następnej wersji R (3.2.0) będzie można powiedzieć

> methods(class=class(temp)) 
[1] [[   coerce  html_form html_node html_nodes html_table 
[7] initialize show  slotsFromS3 
see '?methods' for accessing help and source code 

gdzie „przymusić” Oznacza to, że istnieje metoda S4 dla as(temp, ..."). Rzeczywiste metody są

> x = methods(class=class(temp)) 
There were 18 warnings (use warnings() to see them) 
> attr(x, "info") 
                visible from  generic isS4 
coerce,oldClass,S3-method       TRUE   coerce TRUE 
coerce,XMLAbstractDocument,XMLAbstractNode-method TRUE XML  coerce TRUE 
coerce,XMLDocument,XMLInternalDocument-method  TRUE XML  coerce TRUE 
coerce,XMLInternalDocument,character-method   TRUE XML  coerce TRUE 
coerce,XMLInternalDocument,XMLHashTree-method  TRUE XML  coerce TRUE 
coerce,XMLInternalDocument,XMLInternalNode-method TRUE XML  coerce TRUE 
coerce,XMLInternalNode,XMLInternalDocument-method TRUE XML  coerce TRUE 
initialize,oldClass-method       TRUE  initialize TRUE 
show,oldClass-method         TRUE    show TRUE 
slotsFromS3,oldClass-method       TRUE  slotsFromS3 TRUE 

Z drugiej strony istnieje

> methods(class="matrix") 
[1] anyDuplicated as.data.frame as.raster  boxplot  coerce  
[6] determinant duplicated edit   head   initialize 
[11] isSymmetric Math   Math2   Ops   relist  
[16] subset  summary  tail   unique  
see '?methods' for accessing help and source code 

gdzie widzimy metod as.data.frame() i as.raster() dostępny na zmuszaniu matrycy.

+0

Dzięki. Wiele do zrobienia, za jednym zamachem. Muszę zajrzeć do klas S3 i S4. –

Powiązane problemy