2013-02-26 18 views
5

ile ayrılır Bir satırda iki soru sormaktan gerçekten nefret ediyorum, ancak bu, kafamı saramayacağım bir şey. R (sadece önceki gün değil önceki sonucunu ve ) akşam değerini önceki ardışık gün arasındaki farkı almak içinFarklı satır ve sütunlar üzerinde çıkarma ve grup

df 
    Row# User Morning  Evening  Measure Date 
    1 1   NA   NA   2/18/11 
    2 1   50   115   2/19/11 
    3 1   85   128   2/20/11 
    4 1   62   NA   2/25/11 
    5 1   48   100.8  3/8/11 
    6 1   19   71   3/9/11 
    7 1   25   98   3/10/11 
    8 1   NA   105   3/11/11 
    9 2   48   105   2/18/11 
    10 2   28   203   2/19/11 
    11 2   35   80.99  2/21/11 
    12 2   91   78.25  2/22/11 

mümkün mü: Yani şöyle ben, bir veri çerçevesi var diyelim Her kullanıcı grubu için 1 satır ve farklı bir satırın sabah değeri? Yani istediğim sonuç bu olurdu.

df 
    Row# User Morning  Evening  Date  Difference 
    1  1  NA   NA  2/18/11  NA 
    2  1  50   115  2/19/11  NA 
    3  1  85   129  2/20/11  30 
    4  1  62   NA  2/25/11  NA 
    5  1  48   100.8  3/8/11   NA 
    6  1  19   71  3/9/11   81.8 
    7  1  25   98  3/10/11  46 
    8  1  10   105  3/11/11  88 
    9  2  48   105  2/18/11  NA 
    10  2  28   203  2/19/11  77 
    11  2  35   80.99  2/21/11  NA 
    12  2  91   78.25  2/22/11  -10.01 

Tüm

Yapacak bu sabah değerini almak ve her kullanıcı grubu için önceki ardışık günün akşamı değerinden onu çıkarmak olduğunu istiyorum. Görebildiğiniz gibi, veri çerçevemin bazı bölümleri sabah ve akşam sütunlarında NA değerleri içerir, buna ek olarak, tüm tarihler her bir farklı kullanıcı için ardışık sırada değildir, bu yüzden doğal olarak NA verilmelidir.

Google'da arama yapmayı denedim, ancak farklı sütunlardaki her satır grubu için farklı satırlara işlev uygulayabilme konusunda fazla bilgi yoktu (eğer bu bir anlam ifade ediyorsa).

Denemelerim, bunun birçok varyasyonunu içerir.

df$Difference<-ave((df$Morning,df$Evening), 
        df$User, 
        FUN=function(x){ 
         c('NA',diff(df$Evening-df$Morning)),na.rm=T 
        }) 

Yine, herhangi bir yardım çok takdir edilecektir. Teşekkürler.

+2

Gerçekten sütun adları ... – juba

cevap

4

Not: göstermek girdi verileri ve çıkış verileri aynı değildir. Çıkışta 10 ile değiştirilen bir NA ve son tarih girişte 2/14/11 ve çıkışta 2/22/11 olduğunu.

Çıktının, sonuçla eşleşmesi için bu yanıtı oluşturmak üzere asıl veri olduğunu varsaydım. (Reddedilen, ama şu gerçekten de var) user1342086 en düzenlemek @

df$Diff <- c(NA, head(df$Evening, -1) - tail(df$Morning, -1)) 
df$Diff[which(c(0, diff(as.Date(as.character(df$Measure_Date), 
       format="%m/%d/%Y"))) != 1)] <- NA 

> df 

# Row User Morning Evening Measure_Date Diff 
# 1 1 1  NA  NA  2/18/11  NA 
# 2 2 1  50 115.00  2/19/11  NA 
# 3 3 1  85 128.00  2/20/11 30.00 
# 4 4 1  62  NA  2/25/11  NA 
# 5 5 1  48 100.80  3/8/11  NA 
# 6 6 1  19 71.00  3/9/11 81.80 
# 7 7 1  25 98.00  3/10/11 46.00 
# 8 8 1  10 105.00  3/11/11 88.00 
# 9 9 2  48 105.00  2/18/11  NA 
# 10 10 2  28 203.00  2/19/11 77.00 
# 11 11 2  35 80.99  2/21/11  NA 
# 12 12 2  91 78.25  2/22/11 -10.01 

:

df$Diff[which(diff(df$User) != 0)] <- NA 

"Kullanıcı" tarafından gruplaşma bakmak gibi görünüyor.

+0

İyi yakalama, sanırım sadece düzeltdim. Ama evet, onu belirli senaryoları kapsayacak şekilde değiştirmek için değiştiriyordum. Ama teşekkürler, yarın bu çözümü deneyeceğim. – rj2700

+0

Bunun yalnızca tarihlerin her kullanıcı için kronolojik sırada olduğu ve her bir kullanıcının verilerinin art arda sırada olduğu durumlarda çalışacağını göz önünde bulundurun. –

+0

@Geektrader'in belirttiği gibi, bu, 'User' grubunun da ilgisini çekmiyor. Daha sonra değiştirilmiş bir çözüm sunacağım. Oscar, bu doğru olsa da, "Kullanıcı" ve "Measure_Date" sütunlarında bir "sipariş" çok daha basit olacaktır. – Arun

4

Kör bir ilk vuruş (test edilmemiş). Kullanıcı ve Tarih tarafından önceden sıralanmış olan veri çerçevesine dayanır.

#if necessary, transform your dates from factor to Date 
df$Date <- as.Date(levels(df$Date)[df$Date],format="%m/%d/%y") 

df <- within(df, 
    Difference <- ifelse(c(NA,diff(Measure_Date)) == 1 & diff(User) == 0, 
    c(NA,head(Evening,-1)) - Morning, NA 
) 
) 
+1

(1) Bu düzgün kullanım '#' unutmamalıdır. OP 'diff (Tarih)' ile 'diff (as.Date (as.character (Measure_Date), format ="% m /% d /% Y ")) ile değiştirilmelidir çünkü' factor' olarak yüklenir . – Arun

+0

Teşekkürler, yarın bu çözümü deneyeceğim. – rj2700

+1

Fark ile birlikte (Tarih) == 1 de farketmeniz gerekir (Kullanıcı) == 0 –

2

plyr kullanıyorum, bu yüzden yüklü olduğundan emin olun. Bu çözüm, kullanıcı verileri karıştırılmış olsa bile (yani ardışık satırlarda değil) çalışmalıdır ve tarihler kronolojik sırada değildir.

# Your example data, as you should post it for us to use 
df <- 
structure(list(User = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L), Morning = c(NA, 50L, 85L, 62L, 48L, 19L, 25L, NA, 48L, 
28L, 35L, 91L), Evening = c(NA, 115, 128, NA, 100.8, 71, 98, 
105, 105, 203, 80.99, 78.25), Measure_Date = structure(c(1L, 
2L, 3L, 5L, 9L, 10L, 6L, 7L, 1L, 2L, 4L, 8L), .Label = c("2/18/11", 
"2/19/11", "2/20/11", "2/21/11", "2/25/11", "3/10/11", "3/11/11", 
"3/14/11", "3/8/11", "3/9/11"), class = "factor")), .Names = c("User", 
"Morning", "Evening", "Measure_Date"), class = "data.frame", row.names = c(NA, 
-12L)) 

# As already stated by Arun, you need the date as class Date 
df$Measure_Date <- as.Date(df$Measure_Date, format='%m/%d/%y') 


# Use plyr to procces the dataframe by user 
library(package=plyr) 
ddply(.data=df, .variables='User', 
     .fun=function(x){ 
     # Complete sequence of dates for each user 
     tdf <- data.frame(Measure_Date=seq(from=min(x$Measure_Date), 
              to=max(x$Measure_Date), 
              by='1 day')) 

     # Merge to fill in NAs for unused dates 
     tdf <- merge(tdf, x, all=TRUE) 

     # Put desired values side by side 
     tdf$Evening <- c(NA, tdf$Evening[-length(tdf$Evening)]) 

     # Diference 
     tdf$Difference <- tdf$Evening - tdf$Morning 

     # Return desired value to original data 
     tdf <- tdf[,c('Measure_Date', 'Difference')] 
     x <- merge(x, tdf) 
     x 
     })