R, bir listenin veya veri çerçevesinin öğelerine erişmek için iki farklı yöntem sağlar: []
ve [[]]
.
İkisi arasındaki fark nedir, hangi durumlarda birini diğerinin üzerinde kullanmalıyım?
R, bir listenin veya veri çerçevesinin öğelerine erişmek için iki farklı yöntem sağlar: []
ve [[]]
.
İkisi arasındaki fark nedir, hangi durumlarda birini diğerinin üzerinde kullanmalıyım?
Yanıtlar:
R Dil Tanımı, bu tür soruları yanıtlamak için kullanışlıdır:
R'nin aşağıdaki örneklerle sözdizimi görüntülendiği üç temel dizin oluşturma operatörü vardır
x[i] x[i, j] x[[i]] x[[i, j]] x$a x$"a"
Vektörler ve matrisler için
[[
formlar , formdan bazı küçük anlamsal farklılıklara sahip olmalarına rağmen nadiren kullanılır[
(örneğin, herhangi bir ad veya dimnames özniteliğini düşürür ve karakter indeksleri için kısmi eşleme kullanılır). Tek bir indeks ile çok boyutlu yapılar endekslenmesi, zamanx[[i]]
ya dax[i]
döneri
inci ardışık elemanx
.Listelerde, genellikle
[[
herhangi bir öğeyi seçmek için kullanılır, oysa[
seçilen öğelerin bir listesini döndürür.
[[
Oysa bir şekilde, bir tam sayı veya karakter indisleri kullanılarak seçilecek tek bir eleman sağlar[
vektörler tarafından endeksleme sağlar. Bununla birlikte, bir liste için indeksin bir vektör olabileceğini ve vektörün her elemanının sırayla listeye, seçilen bileşene, o bileşenin seçilen bileşenine vb. Uygulandığını unutmayın. Sonuç hala tek bir unsurdur.
[
zaman bir liste döndürmek x[v]
, uzunluğu ne olursa olsun aynı çıktı sınıfını almanız anlamına gelir v
. Örneğin, bir isteyebilirsiniz lapply
Bir listenin bir alt kümesini aşırı: lapply(x[v], fun)
. Eğer [
uzunluk birinin vektörler için liste düşeceği, bu her bir hata döndürecektir v
uzunluk birine sahiptir.
İki yöntem arasındaki önemli farklar, ayıklama için kullanıldıklarında döndürdükleri nesnelerin sınıfı ve bir değer aralığını mı yoksa atama sırasında yalnızca tek bir değeri mi kabul edip edemeyecekleridir.
Aşağıdaki listede veri çıkarma durumunu göz önünde bulundurun:
foo <- list( str='R', vec=c(1,2,3), bool=TRUE )
Diyelim ki bool tarafından depolanan değeri foo'dan çıkarmak ve bunu bir if()
deyim içinde kullanmak istiyoruz . Bu, veri çıkarımı için dönüş değerleri []
ve [[]]
ne zaman kullanıldıkları arasındaki farkları gösterecektir . []
İse sınıf listesine göre bir yöntem döner nesnelerin (veya data.frame foo eğer data.frame olarak) [[]]
yöntemi döndürür olan sınıf değerlerinin türüne göre belirlenir nesneleri.
Bu nedenle, []
yöntemi kullanmak aşağıdakileri sağlar:
if( foo[ 'bool' ] ){ print("Hi!") }
Error in if (foo["bool"]) { : argument is not interpretable as logical
class( foo[ 'bool' ] )
[1] "list"
Bunun nedeni, []
yöntemin bir liste döndürmesi ve listenin doğrudan bir if()
ifadeye iletilmesi için geçerli bir nesne olmamasıdır . Bu durumda kullanmamız gerekir, [[]]
çünkü uygun sınıfa sahip olacak 'bool' içinde saklanan “çıplak” nesneyi döndürecektir:
if( foo[[ 'bool' ]] ){ print("Hi!") }
[1] "Hi!"
class( foo[[ 'bool' ]] )
[1] "logical"
İkinci fark, []
operatörün bir veri çerçevesindeki bir liste veya sütun aralığına erişmek için kullanılabilmesi ve [[]]
operatörün tek bir yuvaya veya sütuna erişimiyle sınırlı olmasıdır . İkinci bir liste kullanarak değer atama durumunu düşünün bar()
:
bar <- list( mat=matrix(0,nrow=2,ncol=2), rand=rnorm(1) )
Diyelim ki, çubuğun içerdiği verilerle foo'nun son iki yuvasının üzerine yazmak istiyoruz. [[]]
Operatörü kullanmaya çalışırsak , olan budur:
foo[[ 2:3 ]] <- bar
Error in foo[[2:3]] <- bar :
more elements supplied than there are to replace
Bunun nedeni [[]]
, tek bir öğeye erişim ile sınırlıdır. Kullanmamız gerekenler []
:
foo[ 2:3 ] <- bar
print( foo )
$str
[1] "R"
$vec
[,1] [,2]
[1,] 0 0
[2,] 0 0
$bool
[1] -0.6291121
Atama başarılı olurken, foo'daki yuvaların orijinal adlarını koruduğunu unutmayın.
Çift parantez bir liste öğesine erişirken, tek bir parantez size tek bir öğeyle listeyi geri verir.
lst <- list('one','two','three')
a <- lst[1]
class(a)
## returns "list"
a <- lst[[1]]
class(a)
## returns "character"
[]
bir liste [[]]
çıkarır, listedeki öğeleri çıkarır
alist <- list(c("a", "b", "c"), c(1,2,3,4), c(8e6, 5.2e9, -9.3e7))
str(alist[[1]])
chr [1:3] "a" "b" "c"
str(alist[1])
List of 1
$ : chr [1:3] "a" "b" "c"
str(alist[[1]][1])
chr "a"
Sadece burada tekrarlayan indeksleme[[
için donatılmış ekleme .
Bu, @JijoMatthew tarafından yanıtta ima edildi, ancak araştırılmadı.
Belirtildiği gibi ?"[["
, söz dizimi gibi x[[y]]
, nerede length(y) > 1
, şöyle yorumlanır:
x[[ y[1] ]][[ y[2] ]][[ y[3] ]] ... [[ y[length(y)] ]]
Not Bu o değil arasındaki fark üzerinde ana paket ne olması gerektiğini değiştirmek [
ve [[
- yani, eski için kullanıldığını subsetting ve ikincisi kullanılır ayıklanması tek liste öğelerini.
Örneğin,
x <- list(list(list(1), 2), list(list(list(3), 4), 5), 6)
x
# [[1]]
# [[1]][[1]]
# [[1]][[1]][[1]]
# [1] 1
#
# [[1]][[2]]
# [1] 2
#
# [[2]]
# [[2]][[1]]
# [[2]][[1]][[1]]
# [[2]][[1]][[1]][[1]]
# [1] 3
#
# [[2]][[1]][[2]]
# [1] 4
#
# [[2]][[2]]
# [1] 5
#
# [[3]]
# [1] 6
3 değerini almak için şunları yapabiliriz:
x[[c(2, 1, 1, 1)]]
# [1] 3
@ JijoMatthew'un yukarıdaki cevabına geri dönersek şunu hatırlayın r
:
r <- list(1:10, foo=1, far=2)
Özellikle, bu yanlış kullanım sırasında elde etme eğilimimizdeki hataları açıklar [[
:
r[[1:3]]
Hata yeri
r[[1:3]]
: 2. düzeyde yinelemeli dizin oluşturma başarısız oldu
Bu kod gerçekte değerlendirmeye çalıştığından r[[1]][[2]][[3]]
ve r
durdurmaların birinci düzeyde iç içe yerleştirilmesinden dolayı , özyinelemeli indeksleme yoluyla çıkartma girişimi [[2]]
, yani 2. seviyede başarısız oldu .
Hata yeri
r[[c("foo", "far")]]
: alt simge sınırların dışında
Burada, R arıyordu r[["foo"]][["far"]]
, ki bu mevcut değildi, bu yüzden alt sınırı sınır hatalarından alıyoruz.
Bu hataların her ikisi de aynı mesajı verirse, muhtemelen biraz daha yararlı / tutarlı olacaktır.
Her ikisi de alt kümelenmenin yollarıdır. Tek köşeli ayraç listenin kendi içinde bir liste olan bir alt kümesini döndürür. yani: Birden fazla eleman içerebilir veya içermeyebilir. Öte yandan, çift köşeli ayraç listeden yalnızca bir öğe döndürür.
-Tek ayraç bize bir liste verecektir. Listeden birden fazla öğe döndürmek istiyorsak, tek köşeli ayraç da kullanabiliriz. aşağıdaki listeyi göz önünde bulundurun: -
>r<-list(c(1:10),foo=1,far=2);
Şimdi listeyi görüntülemeye çalıştığımda listenin nasıl döndürüldüğüne dikkat edin. R yazıp enter tuşuna basarım
>r
#the result is:-
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
$foo
[1] 1
$far
[1] 2
Şimdi tek bir parantez büyüsünü göreceğiz: -
>r[c(1,2,3)]
#the above command will return a list with all three elements of the actual list r as below
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
$foo
[1] 1
$far
[1] 2
Bu, ekranda r değerini görüntülemeye çalıştığımızla tamamen aynı, yani tek bir parantez kullanımı bir liste döndürdü, burada dizin 1'de 10 öğeden oluşan bir vektörümüz var, o zaman foo adlarına sahip iki öğemiz daha var ve uzak. Tek parantez içine girdi olarak tek bir dizin veya öğe adı vermeyi de seçebiliriz. Örneğin:
> r[1]
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
Bu örnekte bir dizin "1" verdik ve karşılığında bir öğe içeren bir liste aldık (10 sayıdan oluşan bir dizi)
> r[2]
$foo
[1] 1
Yukarıdaki örnekte bir dizin "2" verdik ve karşılığında bir öğe içeren bir liste aldık
> r["foo"];
$foo
[1] 1
Bu örnekte bir öğenin adını geçtik ve karşılığında bir öğeyle birlikte bir liste döndürüldü.
Ayrıca, aşağıdakiler gibi öğe adlarının bir vektörünü de iletebilirsiniz: -
> x<-c("foo","far")
> r[x];
$foo
[1] 1
$far
[1] 2
Bu örnekte "foo" ve "far" olmak üzere iki öğe adında bir vektör geçtik
Karşılığında iki unsurlu bir liste aldık.
Kısacası, tek bir parantez size her zaman eleman sayısına veya tek parantez içine ilettiğiniz indeks sayısına sahip başka bir liste döndürür.
Buna karşılık, çift köşeli parantez her zaman yalnızca bir öğe döndürür. Çift köşeli paranteze taşınmadan önce akılda tutulması gereken bir not.
NOTE:THE MAJOR DIFFERENCE BETWEEN THE TWO IS THAT SINGLE BRACKET RETURNS YOU A LIST WITH AS MANY ELEMENTS AS YOU WISH WHILE A DOUBLE BRACKET WILL NEVER RETURN A LIST. RATHER A DOUBLE BRACKET WILL RETURN ONLY A SINGLE ELEMENT FROM THE LIST.
Birkaç örnek vereceğim. Lütfen kelimeleri kalın bir şekilde not edin ve aşağıdaki örneklerle işiniz bittikten sonra tekrar yazın:
Çift braket endeksinde size gerçek değerini döndürecektir. (Bu olacak DEĞİL listesini döndürür)
> r[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
>r[["foo"]]
[1] 1
çift köşeli parantezler için, bir vektörü ileterek birden fazla öğeyi görüntülemeye çalışırsak, yalnızca bu ihtiyaca cevap vermek için tasarlanmadığı için değil, yalnızca tek bir öğeyi döndürmek için hataya neden olur.
Aşağıdakileri göz önünde bulundur
> r[[c(1:3)]]
Error in r[[c(1:3)]] : recursive indexing failed at level 2
> r[[c(1,2,3)]]
Error in r[[c(1, 2, 3)]] : recursive indexing failed at level 2
> r[[c("foo","far")]]
Error in r[[c("foo", "far")]] : subscript out of bounds
Yeni başlayanların manuel siste gezinmesine yardımcı olmak için [[ ... ]]
gösterimi daraltma işlevi olarak görmek yararlı olabilir - başka bir deyişle, sadece adlandırılmış bir vektör, liste veya veri çerçevesinden 'verileri almak' istersiniz. Hesaplamalar için bu nesnelerden veri kullanmak istiyorsanız bunu yapmak iyi olur. Bu basit örnekler açıklanacaktır.
(x <- c(x=1, y=2)); x[1]; x[[1]]
(x <- list(x=1, y=2, z=3)); x[1]; x[[1]]
(x <- data.frame(x=1, y=2, z=3)); x[1]; x[[1]]
Üçüncü örnekten:
> 2 * x[1]
x
1 2
> 2 * x[[1]]
[1] 2
iris[[1]]
bir vektör iris[1]
döndürürken bir veri döndürür.
Terminolojik olarak, [[
operatör özler ise bir listeden öğeyi [
alan operatör alt kümesi , bir liste.
Bir başka somut kullanım durumunda, split()
fonksiyon tarafından oluşturulan bir veri çerçevesi seçmek istediğinizde çift parantez kullanın . Bilmiyorsanız, split()
bir listeyi / veri çerçevesini anahtar alanına göre altkümeler halinde gruplandırır. Birden fazla grupta çalışmak, bunları çizmek vb. İçin yararlıdır.
> class(data)
[1] "data.frame"
> dsplit<-split(data, data$id)
> class(dsplit)
[1] "list"
> class(dsplit['ID-1'])
[1] "list"
> class(dsplit[['ID-1']])
[1] "data.frame"
Lütfen aşağıdaki ayrıntılı açıklamaya bakın.
R'de mtcars adı verilen yerleşik veri çerçevesini kullandım.
> mtcars
mpg cyl disp hp drat wt ...
Mazda RX4 21.0 6 160 110 3.90 2.62 ...
Mazda RX4 Wag 21.0 6 160 110 3.90 2.88 ...
Datsun 710 22.8 4 108 93 3.85 2.32 ...
............
Tablonun en üst satırına sütun adlarını içeren başlık denir. Ardından her yatay çizgi, satır adıyla başlayan ve ardından gerçek verilerle başlayan bir veri satırını gösterir. Bir satırdaki her veri üyesine hücre denir.
Bir hücredeki verileri almak için, satır ve sütun koordinatlarını tek köşeli parantez "[]" operatörüne gireriz. İki koordinat virgülle ayrılır. Başka bir deyişle, koordinatlar satır konumu ile başlar, ardından virgül ile başlar ve sütun konumu ile biter. Sıra önemlidir.
Örnek 1: - İşte ilk sıra, ikinci mtcars sütunundaki hücre değeri.
> mtcars[1, 2]
[1] 6
Örnek 2: - Ayrıca, sayısal koordinatlar yerine satır ve sütun adlarını kullanabiliriz.
> mtcars["Mazda RX4", "cyl"]
[1] 6
Çift köşeli parantez "[[]]" operatörüyle bir veri çerçevesi sütununa başvuruyoruz.
Örnek 1: - Yerleşik veri kümesi mtcar'larının dokuzuncu sütun vektörünü almak için mtcarlar yazıyoruz [[9]].
mtcars [[9]] [1] 1 1 1 0 0 0 0 0 0 0 0 ...
Örnek 2: - Aynı sütun vektörünü adına göre alabiliriz.
mtcars [["am"]] [1] 1 1 1 0 0 0 0 0 0 0 0 ...