dplyr:

2015-05-07 32 views
5

nasıl mutate kullanma hakkında giderdim alıntı değişken adları ile mutasyona için standart değerlendirme (benim karinesi ben dolayısıyla mutate_ benim durumumda standart değerlendirme için arıyorum ve bu, ama bu noktada tamamen emin değilim) Bu gibi değişken adlarının bir listesini kabul eden bir işlevi kullanırken:dplyr:

library(dplyr) 
library(lazyeval) 

# function to make random table with given column names 
makeTable = function(colNames, sampleSize) { 
    liSample = lapply(colNames, function(week) { 
    sample = rnorm(sampleSize) 
    }) 
    names(liSample) = as.character(colNames) 
    return(tbl_df(data.frame(liSample, check.names = FALSE))) 
} 

# create some sample data with the column name patterns required 
weekDates = seq.Date(from = as.Date("2014-01-01"), 
        to = as.Date("2014-08-01"), by = "week") 
dfTest = makeTable(weekDates, 10) 

# test mutate on this table 
dfTest %>% 
    mutate_(sumvar = interp(~ sum(var, na.rm = TRUE), 
          var = as.name(paste(as.character(weekDates), collapse =",")))) 
: Burada
createSum = function(data, variableNames) { 
    data %>% 
    mutate_(sumvar = interp(~ sum(var, na.rm = TRUE), 
          var = as.name(paste(as.character(variableNames), collapse =",")))) 

} 

onun temel mantığı fonksiyonu şeritler ve MWE olduğunu ben başarmak ne çalışıyorum gösteriyorBurada 0

Beklenen çıkış ziyerete iade edileceği edilir: Bu ne konum olduğunu düşünüyorum

rowSums(dfTest[, as.character(weekDates)]) 
+0

“makeTable” öğesini tanımlarsınız, sonra makeDataFrame işlevini çağırırsınız. Bunların aynı fonksiyon olması mı gerekiyor? Bu örnek giriş için beklediğiniz çıktıyı tanımlamak yararlı olacaktır (veriyi tekrar üretilebilir hale getirin). – MrFlick

+0

@MrFlick Teşekkürler. İşlev adını değiştirdi. Fantezi bir şey beklemez, sadece değişken isimleri satırlara göre işleve geçen tüm değişkenlerin toplamı. Beklenen çıktıyla güncellenir. – tchakravarty

cevap

5

biz sadece ziyade interp daha karakter değerini tedarik

createSum = function(data, variableNames) { 
    data %>% 
     mutate_(sumvar = paste(as.character(variableNames), collapse ="+")) 
} 
createSum(dfTest, weekDates) 

sonra bunu yapamazsınız çünkü isimler listesine tek bir parametre olarak bir işleve geçmek. Ayrıca, sum() bazı istenmeyen çökmeler yapardı çünkü işlemler roxi yapılmaz, bir seferde vektör sütunlarına geçirilir.

Bu örnekteki diğer bir sorun, data.frame öğenizde check.names=FALSE'u ayarlamanızdır; bu, geçerli semboller olamayan sütun adlarını oluşturduğunuz anlamına gelir. Eğer

createSum(dfTest , paste0("`", weekDates,"`")) 

İsterseniz açıkça arka keneler içinde değişken isimleri sarabilirsiniz ama genel olarak geçersiz isimler kullanmamaya daha iyi olurdu.

+0

Teşekkürler, bu işe yarardı, ama eğer işlev kullanışlı bir operatör sembolüne sahip değilse? İkincisi, o zaman nasıl bir argüman listesi ismini '...' fonksiyonuna iletebilirim? Gördüğüm standart değerlendirmenin tek örneği, bir değişken adı içermektedir. – tchakravarty

+0

Bu varsayımsal hakkında konuşmak kolay değildir, her işlev farklı olabilir. Ancak bu dize oluşturma yöntemi diğer birçok işlev için çalışmalıdır ('toplam' bir istisnadır). Sadece macun gibi görünebilir paste0 ("funname (", paste (vars, collapse = ","), ")") ' – MrFlick

+0

Evet, korktuğum gibi, bu korkunç bir sözdizimine benziyor (sizin hatalarınızdan değil!) . Paradigmayı çok iyi anlayabildiğimi sanmıyorum - tek yapabilmem gereken 'data_frame' ortamındaki değişken sembolleri değerlendirmektir. Şüphesiz, hantal ifade oluşturma ya da 'eval (parse (text =)' e başvurmadan bunu yapmak için daha iyi bir yol vardır. – tchakravarty

1

bu bir "resmi olarak onaylanmış" dplyr yolu ise bilmiyorum, ama bu bir ihtimaldir:

weekDates = as.character(weekDates) # more convenient 

dfTest %>% mutate(sumvar = Reduce(`+`, lapply(weekDates, get, .))) 
#or 
dfTest %>% mutate(sumvar = rowSums(as.data.frame(lapply(weekDates, get, .)))) 

Bu taşımak gelmez potansiyel önemli performans cezaları, belirli kullanıma bağlı olarak - ilaveten dplyr'un tüm verileri düzenli olarak kopyaladığını düşünüyorum, aynı zamanda bu dahili hesaplama sırasında ikinci kez kopyalar. Daha fazla kopyalama yapmak için data.table'a bakabilirsiniz, böylece sütunlar ekleyerek (ve ikinci kopyayı önlemek için .SDcols'u kullanın) + daha iyi bir sözdizimi elde edersiniz.