Son zamanlarda R öğreniyorum ve iki işlevle karıştırıyorum: lapply
ve do.call
. Görünüşe göre map
Lisp'teki işleve benzerler . Ama neden böyle farklı bir isme sahip iki fonksiyon var? R neden sadece denilen bir işlevi kullanmıyor map
?
Son zamanlarda R öğreniyorum ve iki işlevle karıştırıyorum: lapply
ve do.call
. Görünüşe göre map
Lisp'teki işleve benzerler . Ama neden böyle farklı bir isme sahip iki fonksiyon var? R neden sadece denilen bir işlevi kullanmıyor map
?
Yanıtlar:
Map
Diğer dillerde haritaya benzeyen bir işlev var :
lapply
her elemanın X'in karşılık gelen elemanına FUN uygulanmasının sonucu olan X ile aynı uzunlukta bir liste döndürür.
do.call
bir ad veya işlevden bir işlev çağrısı ve ona iletilecek argümanların listesini oluşturur ve yürütür.
Map
verilen vektörlerin mukabil elemanlara bir fonksiyonu uygular ... Map
için basit bir sarıcı mapply
(bağımsız Ancak, geri dönüşümlü edilir) Ortak Lisp'in mapcar benzer bir sonuç, basitleştirmek denemez olan. Gelecekteki sürümler, sonuç türünün bir miktar kontrolüne izin verebilir.
Map
etrafı sarmak mapply
lapply
özel bir durum mapply
Map
ve lapply
birçok durumda benzer olacaktır.Örneğin, işte burada lapply
:
lapply(iris, class)
$Sepal.Length
[1] "numeric"
$Sepal.Width
[1] "numeric"
$Petal.Length
[1] "numeric"
$Petal.Width
[1] "numeric"
$Species
[1] "factor"
Ve aynı kullanarak Map
:
Map(class, iris)
$Sepal.Length
[1] "numeric"
$Sepal.Width
[1] "numeric"
$Petal.Length
[1] "numeric"
$Petal.Width
[1] "numeric"
$Species
[1] "factor"
do.call
bir işlevi girdi olarak alır ve diğer bağımsız değişkenlerini işleve sıçrar. Örneğin, listeleri daha basit yapılara (genellikle rbind
veya ile cbind
) birleştirmek için yaygın olarak kullanılır .
Örneğin:
x <- lapply(iris, class)
do.call(c, x)
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
"numeric" "numeric" "numeric" "numeric" "factor"
do.call(cbind, x)
Geçerli sürüm olması gerekiyordu son örnek bana verir değil Error in do.call(c, x) : 'what' must be a function or character string
...
cbind()
, işlevden farklıdır c()
ve bu da çalışmasına rağmen farklı sonuçlar verir.
lapply
bir işlevi listenin üzerine uygular do.call
, bağımsız değişkenlerin listesini içeren bir işlevi çağırır. Bu benim için bir fark gibi görünüyor ...
Listeli bir örnek vermek için:
X <- list(1:3,4:6,7:9)
Lapon ile listedeki her elementin ortalamasını şöyle elde edersiniz:
> lapply(X,mean)
[[1]]
[1] 2
[[2]]
[1] 5
[[3]]
[1] 8
do.call
ortalama "trim" argümanının 1 olmasını beklediği için bir hata verir.
Öte yandan, rbind
tüm argümanları bağlar. X rowwise'ı bağlamak için şunları yaparsınız:
> do.call(rbind,X)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
Kullanırsanız lapply
, R rbind
listenin her öğesine uygulanır ve size bu saçmalığı verir:
> lapply(X,rbind)
[[1]]
[,1] [,2] [,3]
[1,] 1 2 3
[[2]]
[,1] [,2] [,3]
[1,] 4 5 6
[[3]]
[,1] [,2] [,3]
[1,] 7 8 9
Harita gibi bir şeye sahip olmak için ihtiyacınız ?mapply
olan şey, bu tamamen farklı bir şey. Örneğin X'deki her öğenin ortalamasını almak için, ancak farklı bir kırpma ile şunları kullanabilirsiniz:
> mapply(mean,X,trim=c(0,0.5,0.1))
[1] 2 5 8
lapply
benzer map
, do.call
değil. lapply
bir işlevi bir listenin tüm öğelerine uygular, do.call
tüm işlev bağımsız değişkenlerinin bir listede bulunduğu bir işlevi çağırır. Bir Yani n
eleman listesinde, lapply
sahip n
işlev çağrıları ve do.call
sadece bir işlev çağrısı vardır. Yani do.call
bundan oldukça farklı lapply
. Umarım bu sorununuzu açıklığa kavuşturur.
Kod örneği:
do.call(sum, list(c(1, 2, 4, 1, 2), na.rm = TRUE))
ve:
lapply(c(1, 2, 4, 1, 2), function(x) x + 1)
En basit ifadeyle:
lapply () , listedeki her öğe için belirli bir işlevi uygular, böylece birkaç işlev çağrısı olur.
do.call () belirli bir işlevi listeye bir bütün olarak uygular, bu nedenle yalnızca bir işlev çağrısı vardır.
Öğrenmenin en iyi yolu, R belgelerindeki işlev örnekleri ile oynamaktır.
Birçok yanıt olmasına rağmen, işte referans için örnek. Bir veri listemiz olduğunu varsayalım:
L=list(c(1,2,3), c(4,5,6))
İşlev lapply bir liste döndürür.
lapply(L, sum)
Yukarıdaki, aşağıdaki gibi bir şey anlamına gelir.
list( sum( L[[1]]) , sum( L[[2]]))
Şimdi do.call için de aynı şeyi yapalım
do.call(sum, L)
Anlamı
sum( L[[1]], L[[2]])
Örneğimizde, 21 döndürür. Kısacası, do.call dönüş türü gerçekten yürütülen işleve bağlıyken lapply her zaman bir liste döndürür.
Her ikisi arasındaki fark:
lapply(1:n,function,parameters)
=> Bu gönderme 1, parametreler fonksiyona => bu 2 gönderir, fonksiyona parametreler vb.
do.call
Sadece vektör olarak 1… n ve fonksiyon olarak parametreler gönderir
Yani uygulamada n fonksiyon çağrınız var, do.call içinde sadece bir tane var
do.call
neredeyseapply
Lisp ile aynı