genel bakış
Nispeten aşinayım data.table, çok fazla değil dplyr. Ben SO ortaya çıktı bazı dplyrvinyet ve örnekleri okudum ve şimdiye kadar benim sonuçları şunlardır:
data.tablevedplyrçok sayıda (yani> 10-100K) grup ve diğer bazı durumlarda (aşağıda kıyaslamalara bakın) hariç, karşılaştırılabilirdplyrdaha erişilebilir sözdizimi vardplyrpotansiyel DB etkileşimlerini özetler (veya alacaktır)- Bazı küçük işlevsellik farklılıkları vardır (aşağıdaki "Örnekler / Kullanım" a bakın)
Zihnimde 2. çok fazla ağırlık taşımıyor çünkü oldukça aşinayım data.table, ancak her ikisi için de yeni kullanıcılar için büyük bir faktör olacağını anlıyorum. Bu konuda daha sezgisel olan bir tartışmadan kaçınmak istiyorum, çünkü zaten aşina olan birinin bakış açısıyla sorulan özel sorumla alakasız data.table. Ayrıca "daha sezgisel" in daha hızlı analize nasıl yol açtığı hakkında bir tartışma yapmaktan kaçınmak istiyorum (kesinlikle doğrudur, ancak yine, burada en çok ilgilendiğim şey değil).
Soru
Bilmek istediğim şey:
- Paketlere aşina olan insanlar için bir veya diğer paketle kodlanması çok daha kolay olan analitik görevler var mı (yani her birinin daha azının iyi bir şey olduğu gerekli ezoterizm seviyesine karşı gerekli tuş vuruşlarının bir kombinasyonu).
- Bir pakette diğerine karşı önemli ölçüde (yani 2 kattan fazla) daha etkin bir şekilde gerçekleştirilen analitik görevler var mı?
Bir son SO soru bana çünkü düşünmediğini nokta kadar, biraz daha bu konuda düşünme var dplyrçok ben zaten neler yapabileceğini ötesinde doğuracağını data.table. İşte dplyrçözüm (Q'nun sonundaki veriler):
dat %.%
group_by(name, job) %.%
filter(job != "Boss" | year == min(year)) %.%
mutate(cumu_job2 = cumsum(job2))
Hangi benim bir data.tableçözüm kesmek kesmek den çok daha iyi oldu . Bununla birlikte, iyi data.tableçözümler de oldukça iyi (teşekkürler Jean-Robert, Arun ve burada kesinlikle en uygun çözüm üzerinde tek bir ifadeyi tercih ettim):
setDT(dat)[,
.SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)],
by=list(id, job)
]
İkincisinin sözdizimi çok ezoterik görünebilir, ancak alışkınsanız aslında oldukça basittir data.table(yani daha ezoterik numaralardan bazılarını kullanmazsanız).
İdeal olarak görmek istediğim bazı iyi örneklerin dplyrya da data.tableyolun daha özlü olması ya da önemli ölçüde daha iyi performans göstermesidir.
Örnekler
kullanımdplyrrastgele sayıda satır döndüren gruplanmış işlemlere izin vermez ( eddi'nin sorusundan , not: bu dplyr 0.5'de uygulanacak gibi görünüyor , ayrıca @beginneRdo@ eddi sorusunun cevabında potansiyel bir geçici çözüm gösterir ).data.tabledestekler haddeleme katılır sıra (sayesinde @dholstius) olarak üst üste katılırdata.tableaynı temel R sözdizimini kullanırken ikili arama kullanan otomatik indeksleme yoluyla formun ifadeleriniDT[col == value]veya hızDT[col %in% values]için dahili olarak optimize eder . Daha fazla ayrıntı ve küçük bir kıyaslama için buraya bakın .dplyrProgramlı kullanımını basitleştirebilen fonksiyonların standart değerlendirme versiyonlarını sunar (örneğinregroup, programlı kullanımının kesinlikle mümkün olduğunu unutmayın , sadece en azından bilgim için bazı dikkatli düşünce, ikame / alıntı, vb. gerektirir)summarize_each_dplyrdata.table
- Kendi ölçütlerimi çalıştırdım ve her iki paketin de "bölünmüş uygulama birleştir" stil analizinde karşılaştırılabilir olduğunu gördüm , ancak çok fazla sayıda grup (> 100K) olduğunda, bu noktada
data.tableönemli ölçüde daha hızlı olur. - @Arun , ölçeklerde grup sayısı arttıkça daha iyi olduğunu gösteren bazı ölçütler çalıştırdı (hem paketlerde hem de R'nin son sürümlerinde güncellenen). Ayrıca, almaya çalışırken bir kriter benzersiz değerleri vardır hızlı ~ 6x.
data.tabledplyrdata.table - (Doğrulanmamış)
data.tablebir grubun daha büyük sürümlerinde% 75 daha hızlıdır / uygula / sıraladplyr, daha küçük olanlarda% 40 daha hızlıdır (yorumlardan başka bir SO sorusu , teşekkürler danas). - Matt, ana yazarı
data.table, etti işlemleri gruplandırma benchmarkeddata.table,dplyrve pitonpandaskadar 2 milyar satır (RAM içinde ~ 100GB) üzerinde . - Bir 80K gruplara eski kriter vardır
data.tablehızlı ~ 8x
Veri
Bu, soru bölümünde gösterdiğim ilk örnek içindir.
dat <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L), name = c("Jane", "Jane", "Jane", "Jane",
"Jane", "Jane", "Jane", "Jane", "Bob", "Bob", "Bob", "Bob", "Bob",
"Bob", "Bob", "Bob"), year = c(1980L, 1981L, 1982L, 1983L, 1984L,
1985L, 1986L, 1987L, 1985L, 1986L, 1987L, 1988L, 1989L, 1990L,
1991L, 1992L), job = c("Manager", "Manager", "Manager", "Manager",
"Manager", "Manager", "Boss", "Boss", "Manager", "Manager", "Manager",
"Boss", "Boss", "Boss", "Boss", "Boss"), job2 = c(1L, 1L, 1L,
1L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L)), .Names = c("id",
"name", "year", "job", "job2"), class = "data.frame", row.names = c(NA,
-16L))
dplyrve data.tablebir cevap bir noktada olacak böylece ekipleri, kriterler üzerinde çalışıyoruz. # 2 (sözdizimi) imO kesinlikle yanlış, ama bu açıkça görüş alanına giriyor, bu yüzden de kapatmak için oy veriyorum.
(d)plyrölçüsü 0
dplyrve plyrsözdizimi açısından ve temelde onların sözdizimi sevmediğim ana nedeni de budur, ben çok fazla yol adları ile ekstra fonksiyonlar ((1'den fazla okuyun) öğrenmek zorunda olduğunu olduğunu hala benim için anlamlı değil), ne yaptıklarını, hangi argümanları aldıklarını, vb. hatırla.
.SD) öğrenmem gerektiğidir . [ciddi olarak] Bunların farklı insanlara hitap edecek meşru tasarım farklılıkları olduğunu düşünüyorum
dplyras.data.table(dat)[, .SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)], by = list(name, job)]