Lapply ve do.call arasındaki fark nedir?


143

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:


126

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.


  1. Map etrafı sarmak mapply
  2. lapply özel bir durum mapply
  3. Bu nedenle Mapve 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" 

4
Aslında bulduğum do.callneredeyse applyLisp ile aynı
Hanfei Sun

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...
sindri_baldur

1
@snoram Bu örnek hala işe yarıyor. İşlev cbind(), işlevden farklıdır c()ve bu da çalışmasına rağmen farklı sonuçlar verir.
Andrie

61

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

34

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)

25

En basit ifadeyle:

  1. lapply () , listedeki her öğe için belirli bir işlevi uygular, böylece birkaç işlev çağrısı olur.

  2. 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.


12

lapply()harita benzeri bir işlevdir. do.call()farklı. Bağımsız değişkenleri numaralandırmak yerine liste biçimindeki bir işleve geçirmek için kullanılır. Örneğin,

> do.call("+",list(4,5))
[1] 9

10

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.


5

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

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.