Son zamanlarda R öğreniyorum ve iki işlevle karıştırıyorum: lapplyve do.call. Görünüşe göre mapLisp'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: lapplyve do.call. Görünüşe göre mapLisp'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:
MapDiğ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.
Mapverilen vektörlerin mukabil elemanlara bir fonksiyonu uygular ... Mapiç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 mapplylapply özel bir durum mapplyMapve lapplybirç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.callbir 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 rbindveya 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.
lapplybir 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, rbindtü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 rbindlistenin 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 ?mapplyolan ş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
lapplybenzer map, do.calldeğil. lapplybir işlevi bir listenin tüm öğelerine uygular, do.calltüm işlev bağımsız değişkenlerinin bir listede bulunduğu bir işlevi çağırır. Bir Yani neleman listesinde, lapplysahip nişlev çağrıları ve do.callsadece bir işlev çağrısı vardır. Yani do.callbundan 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.callneredeyseapplyLisp ile aynı