()

2015-11-25 33 views
5

içinde birden çok adlandırılmış liste bileşenini kaldırma within ve rm kullanarak bir listeden adlandırılmış bir bileşeni kaldırmaya çalışıyorum. Bu, tek bir bileşen için çalışır, ancak iki veya daha fazla değil. Tamamen şaşkınım.()

Örneğin - bu within çıktısı sadece olmayan kaldırılan bileşenlere sahip olacak

aa = list(a = 1:3, b = 2:5, cc = 1:5) 
within(aa, {rm(a)}) 

çalışır.

Ancak bu değildir:

aa = list(a = 1:3, b = 2:5, cc = 1:5) 
within(aa, {rm(a); rm(b)}) 

da yok bu:

within çıktısı NULL ayarlı Kaldırtmak çalışıyorum olanlar ile tüm bileşenleri sahip olacaktır
within(aa, {rm(a, b)}) 

. Niye ya?

+0

'aa ['a'] <- NULL'? – etienne

+0

Eh, evet. Ama bunu – martin

+0

içinde yapmaya çalışıyorum. Bu garip bir davranış! Birini silebilirsiniz, ancak bundan sonra 3'den fazla sütun olsa bile NULL olarak kalırlar. (Aa, {"b" <- NULL; "a" <- NULL}) ' – jeremycg

cevap

4

Önce, aşağıdaki davranış dikkat edin:

> 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 

Şimdi within.list için kod bakalım: fonksiyonunun son çizgiye saniyede özellikle

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 
} 

bak. Listedeki silinen öğelerin sayısı birden fazlaysa, işlev, vector("list", 2) her öğenin NULL olduğu iki öğe listesi oluşturduğundan, temel olarak aa[c('a', 'b')] <- list(NULL, NULL) çağırır. Şimdi

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 
} 

test edelim: Biz fonksiyonun son satırına ikinci gelen else deyimi kaldırmak nerede within bizim kendi sürümünü oluşturabilirsiniz

> aa = list(a = 1:3, b = 2:5, cc = 1:5) 
> 
> mywithin(aa, rm(a, b)) 
# $cc 
# [1] 1 2 3 4 5 

Şimdi beklenen işleri olarak!

+0

Ah ile benzer şekilde çalışır. Kaynağa bakmayı düşünmüş olmalı. Çok minnettarım! – martin

+0

Bu çok düzgün, ancak niçin 'içerdekiler listesinden kaldırılmalı? ve bir hata olduğunu varsayalım, lütfen 'base :: inside' üzerinde bir R hatası – smci