Kısa arka plan: Yaygın kullanımdaki birçok (en çok?) Çağdaş programlama dili, en azından bir avuç ADT'ye sahiptir (özellikle soyut veri türleri),
string (karakterlerden oluşan bir dizi)
liste (sıralı değerler koleksiyonu) ve
harita tabanlı tür (anahtarları değerlerle eşleyen sıralanmamış bir dizi)
R programlama dilinde, ilk ikisi sırasıyla character
ve olarak uygulanır vector
.
R öğrenmeye başladığımda, neredeyse en başından itibaren iki şey açıktı: list
R'deki en önemli veri türü (çünkü R'nin ana sınıfı olduğu data.frame
) ve ikincisi, en azından nasıl çalıştıklarını anlayamadım, en azından kodumda doğru kullanmak için yeterince iyi değil.
Bir kere, R'nin list
veri türünün ADT haritasının ( dictionary
Python'da, NSMutableDictionary
Objective C'de, hash
Perl ve Ruby'de, object literal
Javascript'te vb.) Doğrudan bir uygulaması olduğu görülüyordu .
Örneğin, bunları bir Python sözlüğünde yaptığınız gibi, anahtar / değer çiftlerini bir kurucuya (Python'da dict
olmayan list
) ileterek oluşturursunuz :
x = list("ev1"=10, "ev2"=15, "rv"="Group 1")
R Listesinin öğelerine tıpkı bir Python sözlüğünde olduğu gibi erişirsiniz, örn x['ev1']
. Benzer şekilde, yalnızca 'anahtarları' veya yalnızca 'değerleri' şu yollarla alabilirsiniz :
names(x) # fetch just the 'keys' of an R list
# [1] "ev1" "ev2" "rv"
unlist(x) # fetch just the 'values' of an R list
# ev1 ev2 rv
# "10" "15" "Group 1"
x = list("a"=6, "b"=9, "c"=3)
sum(unlist(x))
# [1] 18
fakat R list
ler de vardır aksine (dil Zaten öğrendiğim arasından) diğer harita tipi ADTS. Tahminimce bu, S için ilk spesifikasyonun bir sonucudur, yani sıfırdan bir veri / istatistik DSL [alana özgü dil] tasarlama niyetidir.
list
yaygın kullanımda R'ler ve diğer dillerdeki haritalama türleri arasındaki üç önemli fark (ör. Python, Perl, JavaScript):
ilk olarak , list
R'deki s değerleri, değerler anahtarlanmış olsa bile, tıpkı vektörler gibi sıralı bir koleksiyondur (yani, anahtarlar sadece sıralı tamsayılar değil, herhangi bir yıkanabilir değer olabilir). Neredeyse her zaman, diğer dillerde eşleme veri türü sıralı değildir .
ikinci olarak , list
işlevi list
çağırdığınızda hiçbir zaman geçmeseniz bile işlevlerden döndürülebilir ve döndüren işlev list
bir (açık) list
yapıcı içermese de (Tabii ki, bunu pratikte döndürülen sonucun çağrısında kaydırılması unlist
):
x = strsplit(LETTERS[1:10], "") # passing in an object of type 'character'
class(x) # returns 'list', not a vector of length 2
# [1] list
R'lerin üçüncü bir tuhaf özelliği list
: başka bir ADT'nin üyesi olabileceği görülmüyor ve bunu yapmaya çalışırsanız birincil kapsayıcı a'ya zorlanıyor list
. Örneğin,
x = c(0.5, 0.8, 0.23, list(0.5, 0.2, 0.9), recursive=TRUE)
class(x)
# [1] list
buradaki amacım dili veya nasıl belgelendiğini eleştirmek değil; aynı şekilde, list
veri yapısı veya nasıl davrandığı ile ilgili yanlış bir şey olduğunu da söylemiyorum . Sonra tüm düzeltmek için nasıl onlar benim kodu doğru kullanmak böylece nasıl çalıştığını anlamaktır.
İşte daha iyi anlamak istediğim şeyler:
Bir işlev çağrısının ne zaman geri döneceğini belirleyen kurallar nelerdir
list
(örneğinstrsplit
yukarıda belirtilen ifade)?Açık bir şekilde
list
(örneğinlist(10,20,30,40)
) ad atamazsam , varsayılan adlar 1 ile başlayan sıralı tamsayılar mıdır? (Sanırım, ama cevabın evet olduğundan emin değilim, aksi takdirde bu türlist
bir çağrıyı olmayan bir vektöre zorlayamazdıkunlist
.)Neden bu iki farklı operatörler, do
[]
ve[[]]
geri dönmek aynı sonucu?x = list(1, 2, 3, 4)
her iki ifade de "1" döndürür:
x[1]
x[[1]]
neden bu iki ifade aynı sonucu vermiyor ?
x = list(1, 2, 3, 4)
x2 = list(1:4)
Lütfen beni R Belgelerine yöneltmeyin ( ?list
, R-intro
) - Dikkatle okudum ve yukarıda okuduğum soruların türünü cevaplamama yardımcı olmuyor.
(son olarak, yakın zamanda öğrendim ve bir S4 sınıfı aracılığıyla geleneksel harita tipi davranışı hash
uygulayan bir R Paketi (CRAN'da mevcut) kullanmaya başladım; kesinlikle bu Paketi tavsiye edebilirim.)
list
, R'de bir karma gibi olmadığı yollar listenizde genişlediğini fark etmedim . Söylemeye değer olduğunu düşündüğüm bir tane daha var. list
R'de aynı referans adına sahip iki üye olabilir. Bunun obj <- c(list(a=1),list(a=2))
geçerli olduğunu ve 'a' adlı iki adlandırılmış değeri olan bir liste döndürdüğünü düşünün . Bu örnekte, çağrısı obj["a"]
yalnızca eşleşen ilk liste öğesini döndürür. x <- new.env(); x[["a"]] <- 1; x[["a"]] <- 2; x[["a"]]
x = list(1, 2, 3, 4)
, her ikisi de aynı sonucu döndürmez:,x[1]
vex[[1]]
. Birincisi bir liste, ikincisi sayısal bir vektör döndürür. Aşağıda ilerlerken bana Dirk'ün bu soruyu doğru bir şekilde cevaplayan tek kişi olduğunu düşünüyorum.