2011-08-24 14 views
15

Soy consciente de que los valores NULL en las listas a veces puede trip gente. Tengo curiosidad por qué en un caso específico lapply y rapply parecen tratar NULL valores diferente.¿Por qué aplicar Rapply y aplicar NULL de forma diferente?

l <- list(a = 1, c = NULL, d = 3) 

lapply(l,is.null) 
$a 
[1] FALSE 

$c 
[1] TRUE 

$d 
[1] FALSE 

Hasta ahora todo bien. ¿Qué tal si hacemos exactamente lo mismo con rapply?

rapply(l, is.null, how = "replace") 
$a 
[1] FALSE 

$c 
list() 

$d 
[1] FALSE 

Este ejemplo es muy simple y no recursivo, pero ver el mismo comportamiento en rapply con listas anidadas.

Mi pregunta es ¿por qué? Si, como se anuncia en ?rapply, se trata de una 'versión recursiva de lapply', ¿por qué se comportan de manera tan diferente en este caso?

Respuesta

18

Creo que responde a su propia pregunta: porque es recursivo.

No se ve a menudo esto, pero NULL realidad se puede utilizar para indicar una secuencia vacía, ya que es el vacío pairlist (similar a cómo () en el Esquema termina una lista. Internamente, R es muy esquema similar).

Por lo tanto, rapply vuelve a aparecer en la lista vacía, pero no se molesta en convertirlo de nuevo en una bobina cuando está hecho; obtienes una lista vacía regular

En realidad, rapplylapply y en realidad no tratan de manera diferente que NULL:

> lapply(NULL, identity) 
list() 

y se puede ver en el código fuente R (memory.c) que esto es exactamente cómo pairlists están destinados a trabajar:

SEXP allocList(int n) 
{ 
    int i; 
    SEXP result; 
    result = R_NilValue; 
    for (i = 0; i < n; i++) 
     result = CONS(R_NilValue, result); 
    return result; 
} 
+1

1 Para señalando que '' null' es un pairlist' vacía. Entonces parece que estás diciendo que 'rapply' no puede (o no) distinguir entre' NULL' y 'pairlist()'. – joran

+1

@joran 'idéntico (pairlist(), NULL)' :) – Owen