In primo luogo, si noti il seguente comportamento:
> aa = list(a = 1:3, b = 2:5, cc = 1:5)
>
> aa[c('a', 'b')] <- NULL
>
> aa
# $cc
# [1] 1 2 3 4 5
> aa = list(a = 1:3, b = 2:5, cc = 1:5)
>
> aa[c('a', 'b')] <- list(NULL, NULL)
>
> aa
# $a
# NULL
#
# $b
# NULL
#
# $cc
# [1] 1 2 3 4 5
Ora diamo un'occhiata al codice per within.list
:
within.list <- function (data, expr, ...)
{
parent <- parent.frame()
e <- evalq(environment(), data, parent)
eval(substitute(expr), e)
l <- as.list(e)
l <- l[!sapply(l, is.null)]
nD <- length(del <- setdiff(names(data), (nl <- names(l))))
data[nl] <- l
if (nD)
data[del] <- if (nD == 1) NULL else vector("list", nD)
data
}
Cerca in particolare in occasione della penultima riga della funzione. Se il numero di elementi eliminati nell'elenco è maggiore di uno, la funzione chiama essenzialmente aa[c('a', 'b')] <- list(NULL, NULL)
, poiché vector("list", 2)
crea un elenco di due elementi in cui ogni elemento è NULL
. Siamo in grado di creare la nostra versione di within
dove abbiamo rimuovere l'istruzione else
dalla seconda all'ultima riga della funzione:
mywithin <- function (data, expr, ...)
{
parent <- parent.frame()
e <- evalq(environment(), data, parent)
eval(substitute(expr), e)
l <- as.list(e)
l <- l[!sapply(l, is.null)]
nD <- length(del <- setdiff(names(data), (nl <- names(l))))
data[nl] <- l
if (nD) data[del] <- NULL
data
}
Ora Testiamola:
> aa = list(a = 1:3, b = 2:5, cc = 1:5)
>
> mywithin(aa, rm(a, b))
# $cc
# [1] 1 2 3 4 5
Ora funziona come previsto!
'aa ['a'] <- NULL'? – etienne
Beh, sì. Ma sto cercando di farlo all'interno di – martin
Questo è un comportamento strano! puoi eliminarne uno, ma dopo rimangono come NULL - anche se ci sono più di 3 colonne. Funziona in modo simile a 'within (aa, {" b "<- NULL;" a "<- NULL})' – jeremycg