Menu

R'de apply, lapply, sapply: apply Ailesi Anlatımı

apply ailesi - apply, lapply, sapply, vapply, mapply ve tapply - bir fonksiyonu verinizin her elemanı üzerinde çalıştırır. İşte her birinin ne yaptığı ve ne zaman ona uzanmanız gerektiği.

Bu sayfada çalıştırılabilir editörler var - düzenle, çalıştır ve sonucu anında gör.

Tek Cümlede apply Ailesi

apply ailesinin her üyesi aynı işi yapar: bir fonksiyon al ve onu bir yapının her elemanı üzerinde çalıştırıp sonuçları topla. Değişen şey girdi biçimi ve çıktı biçimidir. Harita:

  • apply(m, MARGIN, FUN) - bir matrisin satırları ya da sütunları.
  • lapply(x, FUN) - bir listenin ya da vektörün her elemanı; her zaman bir liste döndürür.
  • sapply(x, FUN) - lapply ile aynı, sonra yapabildiğinde bir vektöre ya da matrise sadeleştirir.
  • vapply(x, FUN, FUN.VALUE) - bildirilmiş ve zorunlu kılınmış dönüş türüyle sapply.
  • mapply(FUN, x, y, ...) - birkaç girdiyi eleman eleman paralel dolaşır.
  • tapply(values, groups, FUN) - FUN fonksiyonunu her grup içinde uygular: grup başına bir sonuç.

Hepsi, isimsiz olanlar dahil kendi yazdığınız fonksiyonları kabul eder; ailenin gücünü aldığı yer burasıdır.

apply(): Bir Matrisin Satırları ve Sütunları

apply bir matris, bir MARGIN (satırlar için 1, sütunlar için 2) ve bir fonksiyon alır:

Matris sütun sütun dolduğu için satırlar 1 3 5 ve 2 4 6'dır: satır toplamları 9 12, sütun toplamları 3 7 11 olarak yazdırılır. En yaygın iki durum için temel R adanmış ve daha hızlı yardımcılar sunar - rowSums, colSums, rowMeans, colMeans - dolayısıyla apply fonksiyonunu apply(m, 2, max) gibi karşılığı olmayan fonksiyonlara saklayın.

Bir tuzak: bir veri çerçevesi üzerindeki apply, onu sessizce önce bir matrise dönüştürür ve bu her sütunu tek bir ortak türe zorlar. Veri çerçeveleri için sütunları bir liste gibi ele alın ve bunun yerine lapply/sapply kullanın.

lapply() Her Zaman Liste Verir, sapply() Sadeleştirir

lapply, bir fonksiyonu her elemana eşler ve ne olursa olsun aynı uzunlukta bir liste döndürür:

Aynı hesap, iki biçim: lapply 85 ve 80 tutan bir liste geri verir; sapply her sonucun uzunluğunun 1 olduğunu fark eder ve isimli bir numeric vektöre sadeleştirir - okuması ve sonraki matematiğe beslemesi çok daha hoştur.

Ama bu kolaylığın keskin bir kenarı vardır: sapply fonksiyonunun dönüş türü veriye bağlıdır. Tek bir eleman bile farklı bir uzunluk üretirse sadeleştirme başarısız olur ve sessizce yine bir liste alırsınız:

Etkileşimli olarak bu omuz silkilecek bir şeydir; bir betiğin içinde ise tüm yıl çalışan kodun, verinin biçim değiştirdiği gün bozulması demektir. vapply fonksiyonunun var olma nedeninin tamamı budur.

vapply(): Tür Güvenli sapply

vapply üçüncü bir argüman ekler, FUN.VALUE: tek bir sonucun nasıl görünmesi gerektiğini bildiren bir şablon. integer(1), "her çağrı tam olarak bir integer döndürür" demektir:

İsimli bir integer vektörü alırsınız - 5 6 6 - ve daha önemlisi bir güvence: nchar bir gün iki değer ya da bir character döndürseydi vapply, biçimi bozuk bir sonucun aşağı akışa süzülmesine izin vermek yerine çağrı yerinde hatayla dururdu. Bildirim aynı zamanda dokümantasyon görevi görür:

vapply(words, nchar, character(1))
# Error in vapply(words, nchar, character(1)) : values must be type 'character'

Genel kural: konsolda sapply, gözetimsiz çalışmak zorunda olan fonksiyonlarda ve betiklerde vapply.

mapply() ve tapply(): Paralel Girdiler ve Gruplar

lapply tek bir yapıyı dolaşır. Her çağrının birkaç yapıdan eşleşen konumlardaki elemanlara ihtiyacı olduğunda mapply kullanın - fonksiyonun önce geldiğine dikkat edin:

Her çıktı elemanı ilk değerleri, sonra ikinci değerleri ve böyle devam ederek eşleştirir: 10 200 3000 40000.

tapply grup bazlı üyedir: values değerlerini groups değişkenine göre böler, fonksiyonu her grup içinde uygular ve grup başına bir sonuç döndürür:

a grubunun ortalaması 30, b grubunun ortalaması 40'tır. Bu, temel R'nin "kategori başına ortalama" sorusuna yanıtıdır - group_by + summarize fonksiyonlarının veri çerçeveleri için yanıtladığı aynı biçimdeki soru; dolayısıyla zaten dplyr bölgesindeyseniz onu kullanın; tapply, elinizde iki yalın vektör olduğunda ve tek satır istediğinizde parlar.

Ailenin tamamında iki kolaylık işe yarar. Fonksiyondan sonraki fazladan argümanlar her çağrıda ona iletilir:

Ve hazır bir fonksiyon uymadığında isimsiz fonksiyonlar devreye girer - sapply(x, \(v) max(v) - min(v)), önce bir yardımcı isimlendirmeden eleman başına bir aralık hesaplar.

apply Ailesi ve for Döngüleri

R'de for döngülerinin yavaş, apply ailesinin hızlı olduğunu duyacaksınız. Bu çoğunlukla efsanedir. Gerçekten yavaş olan şey bir döngü içinde sonucu büyütmektir - result <- c(result, new_value) her turda tüm vektörü kopyalar. Çıktısını önceden ayıran bir döngü gayet iyi performans gösterir:

Yani performansa göre değil okunabilirliğe göre seçin. apply sürümü ne yapıldığını tek satırda söyler - "her elemanın karesini al" - ve ayırmayı sizin yerinize halleder; basit eleman bazlı işlerde deyim olmasının nedeni budur. Bir for döngüsü ise yinelemeler önceki sonuçlara bağlı olduğunda, break ile erken çıkışlara ihtiyaç duyduğunuzda ya da gövde bir lambda'nın faydadan çok zarar vereceği kadar uzun olduğunda ekmeğini çıkarır. İkisi de meşru R'dir.

Buradan Ne Çıkarıyorsunuz

  • Ailenin tamamı tek bir fikirdir: bir fonksiyonu her eleman üzerinde çalıştır, sonuçları topla.
  • apply matris satırları (MARGIN = 1) ve sütunları (MARGIN = 2) içindir; var olduklarında rowSums/colMeans tercih edin.
  • lapply her zaman bir liste döndürür; sapply yapabildiğinde sadeleştirir - yani dönüş türü veriyle birlikte değişebilir.
  • vapply dönüş türünü kilitler; sizi şaşırtmaması gereken kodda kullanın.
  • mapply birkaç girdiyi birbirine geçirir; tapply değerleri gruplar içinde toplulaştırır.
  • for döngüleri doğası gereği yavaş değildir - vektör büyütmek yavaştır. En iyi okunan yazımı seçin.

Sırada: pipe'lar - bu çağrıları okunabilir, adım adım işlem hatlarına zincirleyen operatör.

Sıkça Sorulan Sorular

R'de lapply ile sapply arasındaki fark nedir?

lapply istisnasız her zaman bir liste döndürür. sapply aynı hesabı yapar ve ardından sonucu sadeleştirmeye çalışır - her elemanın uzunluğu 1 ise bir vektöre, ortak bir uzunluk paylaşıyorlarsa bir matrise ve yapamıyorsa yine bir listeye. sapply etkileşimli kullanımda daha hoştur; lapply (ya da vapply) betiklerde daha güvenlidir, çünkü dönüş türü hiç değişmez.

R'de apply() ne yapar?

apply(m, MARGIN, FUN), FUN fonksiyonunu bir matris üzerinde çalıştırır: MARGIN = 1 her satıra, MARGIN = 2 her sütuna uygular. apply(m, 1, sum) satır toplamlarını, apply(m, 2, mean) sütun ortalamalarını verir. Matrisler ve diziler içindir - listeler ve vektörler için lapply/sapply kullanın.

R'de apply ailesi for döngüsünden hızlı mıdır?

Genellikle kayda değer ölçüde değil - bu bir efsanedir. Sonuç vektörü önceden ayrılmış, iyi yazılmış bir for döngüsü benzer performans gösterir. for döngülerine kötü ün kazandıran döngüler, sonuçlarını her turda her şeyi kopyalayarak birer eleman büyütenlerdir. apply ailesi fonksiyonlarını hız için değil, özlülük ve niyet için seçin.

R'de vapply ne için kullanılır?

vapply, bir sözleşmeyle gelen sapplydir: her sonucun türünü ve uzunluğunu bildirirsiniz, ör. vapply(x, nchar, integer(1)). Fonksiyon başka bir şey döndürürse R, beklenmedik bir yapıyı sessizce elinize tutuşturmak yerine anında hata verir. Gözetimsiz çalışmaya devam etmesi gereken kodda bunu tercih edin.

Coddy programming languages illustration

Coddy ile kodlamayı öğren

BAŞLA