2015-05-31 29 views
5

I recently aşağıdaki gruplandırılmış işlemlere ayrıldı: her grup için, değerler -0,5 ile 0,5 arasında eşit dağıtılmış sayılar atanır ve grupta yalnızca bir öğe varsaGruptaki tüm değerleri önemli olan gruplara göre gruplandırma atama

g <- c("A", "A", "B", "B", "A", "C") 

sonra atanmış cekti beklemek değerleri: aşağıdaki gözlenen gruplar olsaydı o zaman, örneğin değerini 0. atanır değerleri ayrıldı grup A'da

outcome <- c(-0.5, 0, -0.5, 0.5, 0.5, 0) 

üç gözlem -0.5 , 0 ve 0,5 (sırayla), iki gözlem Grup B'deki tiyonlar -0.5 ve 0.5 (sırayla), ve C grubundaki bir gözlem 0'a atanmıştı.

Normalde başka bir vektör almak için bir vektör üzerinde gruplandırılmış bir işlem gerçekleştirdiğimde, ave(data.vector, group.vector, FUN=function.to.apply.to.each.groups.data.vector.subset) formu ile ave işlevi. Ancak bu operasyonda bilmem gereken tek şey gruptaki üye sayısıdır, dolayısıyla data.vector yoktur. Sonuç olarak, ben sadece ave benim çağrısında gözardı veri vektörü oluşturan sona erdi:

ave(rep(NA, length(g)), g, FUN=function(x) { 
    if (length(x) == 1) { 
    return(0) 
    } else { 
    return(seq(-0.5, 0.5, length=length(x))) 
    } 
}) 
# [1] -0.5 0.0 -0.5 0.5 0.5 0.0 

bu bana doğru cevabı verirken, bir veri vektörü telafi etmek gerek besbelli oldukça yetersiz olduğunu O zaman görmezden gelirim. Tüm önemli olan, gruptaki öğelerin sayısı olduğunda, gruba göre değerler atamanın daha iyi bir yolu var mı?

+1

data.table'' ile sen.data.table (g) [, res: = if (.N> 1) seq (-0,5, 0,5, uzunluk = .N) başka 0 yapabilmeniz gerekir. Bu daha iyi. –

+1

btw, '' a'' içinde 'g' çalıştırabilirsiniz ve yeni bir vektör oluşturmanıza gerek yoktur, örneğin' as.numeric (ave (g, g, FUN = fonksiyon (x) { ise (uzunluğu (x) == 1) { dönüş (0) } başka { dönüş (devamı (-0.5, 0.5, uzunluğu = uzunluğu (x))) } })) ' –

+2

için 'kaçının olabilir '' else' ile ave (seq_along (g), g, FUN = fonksiyon (x) seq (-0,5, 0,5, uzunluk = uzunluk (x)) * (uzunluk (x)! = 1) + 0L) 'veya kütüphane (dplyr); as.data.frame (g)%>% group_by (g)%>% mutasyon (val = sıra (-0.5, 0.5, uzunluk = n()) * (n()! = 1) + 0L) ' – akrun

cevap

2

Yorumlar sadece ave sürümüne sahip gibi görünmüyor, bu da yalnızca grubu ve her gruptaki öğe sayısıyla adlandırılan bir işlevi alıyor. Sanırım bu oldukça şaşırtıcı bir işlem olmadığından özellikle şaşırtıcı değil.

Sık sık ben ave etrafında ince bir sarıcı olarak istenen özelliklere sahip ave benim kendi versiyonunu rulo olabilir bunu yapmak olsaydı: (veya benzer dplyr` `ile)

ave.len <- function(..., FUN) { 
    l <- list(...) 
    do.call("ave", c(list(x=rep(NA, length(l[[1]]))), l, FUN=function(x) FUN(length(x)))) 
} 

# Original operation, using @akrun's 1-line command for sequences 
g <- c("A", "A", "B", "B", "A", "C") 
ave.len(g, FUN=function(n) seq(-0.5, 0.5, length=n)* (n!=1)+0L) 
# [1] -0.5 0.0 -0.5 0.5 0.5 0.0 

# Group of size n has the n^th letter in the alphabet 
ave.len(g, FUN=function(n) rep(letters[n], n)) 
# [1] "c" "c" "b" "b" "c" "a" 

# Multiple groups via the ... argument (here everything's in own group) 
ave.len(g, 1:6, FUN=function(n) rep(letters[n], n)) 
# [1] "a" "a" "a" "a" "a" "a" 
İlgili konular