2016-02-06 20 views
11

R, x değişkenine göre veri gruplandırdıktan sonra veriyi özetlemek istiyorum (her veri grubu, ardışık x değerlerinin bulunduğu verilerin bir alt kümesine karşılık gelir. aynıdır). I x her çalışması içinde ortalama y değerini hesaplamak istediğiniz Örneğin, aşağıdaki veri çerçevesi göz önünde bulundurun: Bu örnektedplyr kullanırken gruplara göre gruplandırmak için rle'yi kullanın

(dat <- data.frame(x=c(1, 1, 1, 2, 2, 1, 2), y=1:7)) 
# x y 
# 1 1 1 
# 2 1 2 
# 3 1 3 
# 4 2 4 
# 5 2 5 
# 6 1 6 
# 7 2 7 

x değişken daha sonra uzunluk 3, 2, 1 silsileleri olan, ve son olarak 1, bu dört çalışmada 1, 2, 1 ve 2 değerlerini alır. bu gruplarda y karşılık gelen aracı çalıştırmak sayısını hesaplamak için rle kullanarak, 2 veri olarak dat$y geçen 4,5, 6 ve

tapply kullanılarak baz R bu gruplanmış işlemi gerçekleştirmek için kolayca 7. vardır dat$x ve istenen özet fonksiyonu geçmesini:

tapply(dat$y, with(rle(dat$x), rep(seq_along(lengths), lengths)), mean) 
# 1 2 3 4 
# 2.0 4.5 6.0 7.0 

Ben oldukça doğrudan dplyr için bu mantık üzerine taşımak mümkün olacaktır düşündük ama benim girişimleri defa bütün hatalar sona erdi:

library(dplyr) 
# First attempt 
dat %>% 
    group_by(with(rle(x), rep(seq_along(lengths), lengths))) %>% 
    summarize(mean(y)) 
# Error: cannot coerce type 'closure' to vector of type 'integer' 

# Attempt 2 -- maybe "with" is the problem? 
dat %>% 
    group_by(rep(seq_along(rle(x)$lengths), rle(x)$lengths)) %>% 
    summarize(mean(y)) 
# Error: invalid subscript type 'closure' 

tamlığı için kendimi cumsum kullanarak rle çalıştırmak id, head reimplement olabilir ve tail Bunu aşmanın ama okumaya gruplama kod zorlaştırıyor ve tekerleği yeniden icat biraz içerir:

dat %>% 
    group_by(run=cumsum(c(1, head(x, -1) != tail(x, -1)))) %>% 
    summarize(mean(y)) 
#  run mean(y) 
# (dbl) (dbl) 
# 1  1  2.0 
# 2  2  4.5 
# 3  3  6.0 
# 4  4  7.0 

rle tabanlı temel kodlama grubunun dplyr'da başarısız olmasına neden olan nedir ve çalışma kimliğine göre gruplandırırken rle'u kullanmaya devam etmemi sağlayan herhangi bir çözüm var mı? Açıkça bir gruplandırma değişken g daha az ya da işler oluşturursanız

cevap

7

Bir seçenek olarak {} kullanımı gibi görünüyor: sürümleri dplyr gelecek de data.table en rleid fonksiyonun bir eşdeğer olsaydı

dat %>% 
    group_by(yy = {yy = rle(x); rep(seq_along(yy$lengths), yy$lengths)}) %>% 
    summarize(mean(y)) 
#Source: local data frame [4 x 2] 
# 
#  yy mean(y) 
# (int) (dbl) 
#1  1  2.0 
#2  2  4.5 
#3  3  6.0 
#4  4  7.0 

iyi olurdu.

dat %>% 
    tbl_df %>% 
    group_by(yy = with(rle(x), rep(seq_along(lengths), lengths))) %>% 
    summarize(mean(y)) 
Error: cannot coerce type 'closure' to vector of type 'integer' 

dat %>% 
    tbl_dt %>% 
    group_by(yy = with(rle(x), rep(seq_along(lengths), lengths))) %>% 
    summarize(mean(y)) 
Source: local data table [4 x 2] 

    yy mean(y) 
    (int) (dbl) 
1  1  2.0 
2  2  4.5 
3  3  6.0 
4  4  7.0 

Ben dplyr en github sayfasında bir issue olarak bu rapor:

Ben tbl_dt veya data.table girişini kullanırken, ancak bir data.frame veya tbl_df girişini kullanırken bu sorun oluşur fark ettim.

+2

Sorun, üzerinde çalıştıkları görünen bir https://github.com/hadley/dplyr/issues/1400 örneği olarak kapatılmış gibi görünüyor. – josliber

+1

Bu harika. "{}" Grubunun burada grup araması nasıl yapıldığına dair belgeyi açıklayabilir veya bana yönlendirebilir misiniz? Googling "dplyr {}" özellikle etkili değil ama belki bu tür bir arama için süslü bir isim var mı? Teşekkürler! – Jordan

+3

@Jordan, bu dplyr özel bir işlev değil.R tabanından ve 'help ("{") 'i kontrol edebilirsiniz. –

2

: mutate bir hata atar çünkü

> dat %>% transform(g=with(rle(dat$x),{ rep(seq_along(lengths), lengths)}))%>%         
group_by(g) %>% summarize(mean(y)) 
Source: local data frame [4 x 2] 

     g mean(y) 
    (int) (dbl) 
1  1  2.0 
2  2  4.5 
3  3  6.0 
4  4  7.0 

Burada transform kullandı.

İlgili konular