genel bakış
Nispeten aşinayım data.table
, çok fazla değil dplyr
. Ben SO ortaya çıktı bazı dplyr
vinyet ve örnekleri okudum ve şimdiye kadar benim sonuçları şunlardır:
data.table
vedplyr
çok sayıda (yani> 10-100K) grup ve diğer bazı durumlarda (aşağıda kıyaslamalara bakın) hariç, karşılaştırılabilirdplyr
daha erişilebilir sözdizimi vardplyr
potansiyel 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 dplyr
ya da data.table
yolun daha özlü olması ya da önemli ölçüde daha iyi performans göstermesidir.
Örnekler
kullanımdplyr
rastgele 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.table
destekler haddeleme katılır sıra (sayesinde @dholstius) olarak üst üste katılırdata.table
aynı 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 .dplyr
Programlı 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_
dplyr
data.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.table
dplyr
data.table
- (Doğrulanmamış)
data.table
bir 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
,dplyr
ve pitonpandas
kadar 2 milyar satır (RAM içinde ~ 100GB) üzerinde . - Bir 80K gruplara eski kriter vardır
data.table
hı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))
dplyr
ve data.table
bir 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
dplyr
ve plyr
sö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
dplyr
as.data.table(dat)[, .SD[job != "Boss" | year == min(year)][, cumjob := cumsum(job2)], by = list(name, job)]