Bir öğeyi listeden nasıl kaldırabilirim?


275

Bir listem var ve bu listeden tek bir öğeyi kaldırmak istiyorum. Bunu nasıl yapabilirim?

Bu işlev için açık isimlerin referans kılavuzda olacağını düşündüğüm şeyi aramaya çalıştım ve uygun bir şey bulamadım.


Bağımlı olarak değeri "değer 5" veya dizin / dizinler "dizin 5'teki öğe" veya "dizinler c (5: 6,10) ile kaldırmak ister misiniz? yineleniyorsa, yalnızca yinelenenleri, ilk veya son tekrarlamayı mı yoksa tümünü mi kaldırmak istiyorsunuz? Listenin öğe / dizininizi içermesi garanti ediliyor mu? ? düz olması garanti liste mi NA (/ hariç) geçirilir sağlamak veya kaç görüşürüz derin iç içe geçebilir?
SMCI

2
setdiff (myList, elementToRemove)
JStrahl 19:18

Yanıtlar:


218

R'yi hiç bilmiyorum, ama biraz yaratıcı googling beni buraya getirdi: http://tolstoy.newcastle.edu.au/R/help/05/04/1919.html

Oradan anahtar alıntı:

Listelerden öğelerin nasıl kaldırılacağına dair R için açık belgeler bulamıyorum, ancak deneme yanılma bana

myList [[5]] <- BOŞ

5. elemanı kaldıracak ve daha sonra o elemanın silinmesinden kaynaklanan deliği "kapatacaktır". Bu indeks değerlerini muzdarip, Bu yüzden öğeleri bırakarak dikkatli olmalıyım. Listenin arkasından öne doğru çalışmalıyım.

Bir sonraki iş parçacığı bu mesaja cevap devletler:

Listenin bir öğesini silmek için, bkz. S SSS 7.1

Ve R SSS'nin ilgili bölümü şöyle diyor:

... x [i] veya x [[i]] değerini NULL olarak ayarlamayın, çünkü ilgili bileşen listeden kaldırılır.

Bu da size (bir şekilde geriye doğru) bir öğeyi nasıl kaldıracağınızı söylüyor.

Umarım yardımcı olur, ya da en azından sizi doğru yönde yönlendirir.


5
Teşekkürler, mylist [i] <- NULL tam olarak bunu yapmanın yoludur.
David Locke

37
Bu benim için işe yaramadı. Ben alıyorum:Error in list[length(list)] <- NULL : replacement has length zero
wfbarksdale

3
@Aleksandr Levchuck'un gönderisi bana aslında bir vektörle uğraştığımı ve yeni bir nesne yaratmam gerektiğini gösterdi
wfbarksdale

209

Listeyi yerinde değiştirmek istemiyorsanız (örneğin, listeyi bir işleve kaldırılmış bir öğeyle geçirmek için), dizin oluşturmayı kullanabilirsiniz: negatif dizinler "bu öğeyi dahil etme" anlamına gelir.

x <- list("a", "b", "c", "d", "e"); # example list

x[-2];       # without 2nd element

x[-c(2, 3)]; # without 2nd and 3rd

Ayrıca, mantıksal indeks vektörleri de yararlıdır:

x[x != "b"]; # without elements that are "b"

Bu, veri çerçeveleriyle de çalışır:

df <- data.frame(number = 1:5, name = letters[1:5])

df[df$name != "b", ];     # rows without "b"

df[df$number %% 2 == 1, ] # rows with odd numbers only

4
Mantıksal dizininiz yalnızca bir liste öğesinde bu tek "b" öğesi varsa çalışır. Bu şekilde kaldıramazsınız, x$bbir liste öğesinden "b" yi kaldıramazsınız x[[2]] = c("b","k") .
Carl Witthoft

Tek veya birden çok öğeyle ilgili olarak: %in%birden çok öğeye karşı test yapmak için kullanabilirsiniz . “X $ b'yi kaldıramıyorum” ile ne demek istediğinizden emin değilim - tüm sütunu kaldırmak mı demek istiyorsunuz b?
Florian Jenn

30

R'deki bir listenin son öğesini nasıl kaldıracağınız aşağıda açıklanmıştır :

x <- list("a", "b", "c", "d", "e")
x[length(x)] <- NULL

X bir vektör olabilirse, yeni bir nesne oluşturmanız gerekir:

x <- c("a", "b", "c", "d", "e")
x <- x[-length(x)]
  • Listeler ve vektörler için çalışma

@krlmlr: aksine, bu çözüm, koleksiyonun türünde polimorfik olduğu için Florian'ın cevabından daha geneldir.
Dan Barowy

@DanBarowy: Yanılmışım: Bu Chad'in yanıtı (kabul edilen) ve Florian'ın cevabı gibi görünüyor ... Yine de iyi bir kısa özet.
krlmlr

19

Tek satırdaki bir listeden Boş öğeleri kaldırma:

x=x[-(which(sapply(x,is.null),arr.ind=TRUE))]

Şerefe


2
xBoş bir liste olduğunda bu kod kırılır . Kullan compactdan plyryerine bu görev için.
Richie Cotton

Ayrıca listede boş değer yoksa, bu satırı tamamen bırakacak olan -(which(sapply(x,is.null),arr.ind=TRUE))döndürmeler named integer(0).
user3055034

17

Eklemek gerekirse, adlandırılmış bir liste varsa kullanabilirsiniz within.

l <- list(a = 1, b = 2)    
> within(l, rm(a))
$b
[1] 2

Böylece orijinal listenin üzerine yazabilirsiniz

l <- within(l, rm(a)) 

adlı öğeyi alisteden kaldırmak için l.


1
Birden fazla yapmak içinwithin(l, rm(a, b))
Vlad

16

Adlandırılmış bir listeniz varsa ve belirli bir öğeyi kaldırmak istiyorsanız deneyebilirsiniz:

lst <- list(a = 1:4, b = 4:8, c = 8:10)

if("b" %in% names(lst)) lst <- lst[ - which(names(lst) == "b")]

Bu bir liste yapacak lstelemanları ile a, b, c. İkinci satır b, varlığını kontrol ettikten sonra öğeyi kaldırır (bahsedilen @hjv sorunundan kaçınmak için).

ya da daha iyisi:

lst$b <- NULL

Bu şekilde var olmayan bir öğeyi silmeyi denemek sorun olmaz (ör. lst$g <- NULL)


10

Çeşitli liste işlemleri ile ilgilenmek için rlist paketi ( http://cran.r-project.org/web/packages/rlist/index.html ) vardır.

Örnek ( http://cran.r-project.org/web/packages/rlist/vignettes/Filtering.html ):

library(rlist)
devs <- 
  list(
    p1=list(name="Ken",age=24,
      interest=c("reading","music","movies"),
      lang=list(r=2,csharp=4,python=3)),
    p2=list(name="James",age=25,
      interest=c("sports","music"),
      lang=list(r=3,java=2,cpp=5)),
    p3=list(name="Penny",age=24,
      interest=c("movies","reading"),
      lang=list(r=1,cpp=4,python=2)))

list.remove(devs, c("p1","p2"))

Sonuçlar:

# $p3
# $p3$name
# [1] "Penny"
# 
# $p3$age
# [1] 24
# 
# $p3$interest
# [1] "movies"  "reading"
# 
# $p3$lang
# $p3$lang$r
# [1] 1
# 
# $p3$lang$cpp
# [1] 4
# 
# $p3$lang$python
# [1] 2

bu örnekte python veya lang öğeleri nasıl kaldırılabilir?
Arthur Yip

9

Buna hala bir cevaba ihtiyacınız olup olmadığını bilmiyorum ama R ile sınırlı (3 haftalık kendi kendine eğitim R) deneyimimden, NULLözellikle dinamik olarak güncelleme yapıyorsanız ödevi kullanmanın aslında yanlış veya alt optimal olduğunu buldum for-loop gibi bir şeydeki bir liste.

Daha kesin olmak gerekirse,

myList[[5]] <- NULL

hatayı atacak

myList [[5]] <- NULL: değiştirmenin uzunluğu sıfır

veya

değiştirilenden daha fazla eleman tedarik edilir

Daha tutarlı çalıştığımı bulduğum şey

myList <- myList[[-5]]

1
İyi cevap! Ancak, [[-5]]tek köşeli parantez olması gerektiğini düşünüyorum , aksi takdirde öğenin kendisi değil, sadece bu liste öğesinin içeriğinin seçimini kaldırıyorsunuz. En azından çift köşeli parantez kullanmak bana şu hatayı veriyor: "birden fazla eleman seçme girişimi". Benim için ne işleri daha sonra: myList <- myList[-5].
n1k31t4

4

Sadece hızlı bir şekilde eklemek istedim (çünkü cevapların hiçbirinde görmedim), adlandırılmış bir liste için de yapabilirsiniz l["name"] <- NULL. Örneğin:

l <- list(a = 1, b = 2, cc = 3)
l['b'] <- NULL

4

-Öğenin konumu ile birlikte (Negatif işaret) kullanın , örneğin 3. öğe kaldırılacaksayour_list[-3]

Giriş

my_list <- list(a = 3, b = 3, c = 4, d = "Hello", e = NA)
my_list
# $`a`
# [1] 3

# $b
# [1] 3

# $c
# [1] 4

# $d
# [1] "Hello"

# $e
# [1] NA

Listeden tek bir öğeyi kaldır

 my_list[-3]
 # $`a`
 # [1] 3

 # $b
 # [1] 3

 # $d
 # [1] "Hello"

 # $e
 [1] NA

Listeden birden fazla öğeyi kaldırma

 my_list[c(-1,-3,-2)]
 # $`d`
 # [1] "Hello"

 # $e
 # [1] NA

 my_list[c(-3:-5)]
 # $`a`
 # [1] 3

 # $b
 # [1] 3

 my_list[-seq(1:2)]
 # $`c`
 # [1] 4

 # $d
 # [1] "Hello"

 # $e
 # [1] NA

2

Adlandırılmış listeler söz konusu olduğunda bu yardımcı işlevleri yararlı buluyorum

member <- function(list,names){
    ## return the elements of the list with the input names
    member..names <- names(list)
    index <- which(member..names %in% names)
    list[index]    
}


exclude <- function(list,names){
     ## return the elements of the list not belonging to names
     member..names <- names(list)
     index <- which(!(member..names %in% names))
    list[index]    
}  
aa <- structure(list(a = 1:10, b = 4:5, fruits = c("apple", "orange"
)), .Names = c("a", "b", "fruits"))

> aa
## $a
##  [1]  1  2  3  4  5  6  7  8  9 10

## $b
## [1] 4 5

## $fruits
## [1] "apple"  "orange"


> member(aa,"fruits")
## $fruits
## [1] "apple"  "orange"


> exclude(aa,"fruits")
## $a
##  [1]  1  2  3  4  5  6  7  8  9 10

## $b
## [1] 4 5

0

Lapply ve grep kullanarak:

lst <- list(a = 1:4, b = 4:8, c = 8:10)
# say you want to remove a and c
toremove<-c("a","c")
lstnew<-lst[-unlist(lapply(toremove, function(x) grep(x, names(lst)) ) ) ]
#or
pattern<-"a|c"
lstnew<-lst[-grep(pattern, names(lst))]

-1

Buna ne dersin? Yine, endeksleri kullanmak

> m <- c(1:5)
> m
[1] 1 2 3 4 5

> m[1:length(m)-1]
[1] 1 2 3 4

veya

> m[-(length(m))]
[1] 1 2 3 4

1
m bir vektör değil, bir liste
C8H10N4O2

1
Yöntem listeler için işe yarıyor, ancak OP şanslı ve muhtemelen biraz daha parantez istiyor:m[1:(length(m) - 1)]
Gregor Thomas

-1

sayısal endekslerden kaçınmak için şunu kullanabilirsiniz:

a <- setdiff(names(a),c("name1", ..., "namen"))

adlarını silmek namea...nameniçin a. bu listeler için çalışır

> l <- list(a=1,b=2)
> l[setdiff(names(l),"a")]
$b
[1] 2

vektörler için olduğu kadar

> v <- c(a=1,b=2)
> v[setdiff(names(v),"a")]
b 
2

-2

Kullanabilirsiniz which.

x<-c(1:5)
x
#[1] 1 2 3 4 5
x<-x[-which(x==4)]
x
#[1] 1 2 3 5

20
Bu bir değillist
GSee
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.