2013-02-26 88 views
5

द्वारा अलग किया गया मैं वास्तव में एक पंक्ति में दो प्रश्न पूछने से नफरत करता हूं लेकिन यह ऐसा कुछ है जिसे मैं अपने सिर को लपेट नहीं सकता। में अनुसंधान लगातार पिछले दिन के बीच का अंतर (और केवल पिछले दिन, नहीं पिछले परिणाम) की शाम मूल्य लेने के लिएविभिन्न पंक्तियों और स्तंभों पर घटाव और समूह

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 

क्या यह संभव है: तो चलो कहते हैं कि इस प्रकार मैं, एक डेटा फ्रेम जाने प्रत्येक उपयोगकर्ता समूह के लिए 1 पंक्ति और एक अलग पंक्ति के सुबह मूल्य? तो मेरे वांछित परिणाम यह होगा।

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 

सभी मैं चाहता हूँ यह करने के लिए सुबह मान ले और प्रत्येक उपयोगकर्ता समूह के लिए पिछले लगातार दिन की शाम मूल्य से घटा दें करने के लिए है। जैसा कि आप देख सकते हैं, मेरे डेटा फ्रेम के कुछ हिस्सों में सुबह और शाम कॉलम में एनए मान होते हैं, इसके अतिरिक्त, सभी अलग-अलग उपयोगकर्ताओं के लिए सभी तिथियां लगातार क्रम में नहीं होती हैं, इसलिए स्वाभाविक रूप से, NA को असाइन किया जाना चाहिए।

मैंने Google को खोजने का प्रयास किया है लेकिन अलग-अलग कॉलम पर पंक्तियों के प्रत्येक समूह के लिए अलग-अलग पंक्तियों में फ़ंक्शंस लागू करने में सक्षम होने पर अधिक जानकारी नहीं थी (यदि यह कोई समझ में आता है)।

मेरे प्रयासों में इसमें कई बदलाव शामिल हैं।

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

फिर से, किसी भी मदद की सराहना की जाएगी। धन्यवाद।

+2

आपको वास्तव में अपने कॉलम नामों में '#' का उपयोग करना चाहिए ... – juba

उत्तर

4

नोट: इनपुट डेटा आप दिखाने के लिए और आउटपुट डेटा ही नहीं हैं। एक NA है जिसे आउटपुट में 10 द्वारा प्रतिस्थापित किया गया है और अंतिम तिथि 2/14/11 इनपुट में और 2/22/11 आउटपुट में है।

मैंने अनुमान लगाया है कि आउटपुट आपके परिणाम से मेल खाने के लिए यह उत्तर बनाने के लिए मूल डेटा है।

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 

@ user1342086 के संपादन (जो खारिज कर दिया गया था, लेकिन सही वास्तव में था):

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

"उपयोगकर्ता" द्वारा समूह की देखभाल करने लगता है।

+0

भी अच्छी पकड़ की आवश्यकता है, मुझे लगता है कि मैंने इसे ठीक कर दिया है। लेकिन हाँ, मैं इसे विशिष्ट परिदृश्यों को कवर करने के लिए मिलान करने के लिए संशोधित कर रहा था। लेकिन धन्यवाद, मैं कल इस समाधान का प्रयास करूंगा। – rj2700

+0

पर विचार करें कि यह केवल तभी काम करेगा जब तिथियां हमेशा प्रत्येक उपयोगकर्ता के लिए क्रमिक क्रम में होती हैं, और प्रत्येक उपयोगकर्ता का डेटा लगातार पंक्तियों में होता है। –

+0

@ गीकेट्रैडर का उल्लेख है, यह 'उपयोगकर्ता' समूह का भी ख्याल नहीं रखता है। मैं बाद में एक संशोधित समाधान प्रदान करूंगा। ऑस्कर, जबकि यह सत्य है, कॉलम 'उपयोगकर्ता' और' Measure_Date' पर 'ऑर्डर' अधिक सरल होगा। – Arun

4

एक अंधे पहले शॉट (अनचाहे)। उपयोगकर्ता और दिनांक द्वारा पहले से क्रमबद्ध डेटा फ्रेम पर निर्भर करता है।

#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) यह साफ है। ओपी को 'diff (दिनांक) 'को' diff (as.Date (as.character (Measure_Date), प्रारूप = "% m /% d /% y" के साथ प्रतिस्थापित करना होगा)) क्योंकि इसे' कारक 'के रूप में लोड किया गया है । – Arun

+0

धन्यवाद, मैं कल इस समाधान का प्रयास करूंगा। – rj2700

+1

diff (दिनांक) == 1 के साथ आपको diff (उपयोगकर्ता) == 0 –

2

मैंने plyr का उपयोग किया, तो सुनिश्चित करें कि आपने इसे इंस्टॉल किया है। यह समाधान तब भी काम करना चाहिए जब उपयोगकर्ता डेटा मिश्रित हो (i.e. लगातार पंक्तियों में नहीं) और तिथियां क्रमिक क्रम में नहीं हैं।

# 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 
     })