2016-07-21 22 views
2

Ich bin neu in R und lerne Grundkenntnisse. Ich habe einen Datenrahmen in R mit Spalten wie controller_id, user_id, mth_id, col_val1 bis col_val100.Unterschied zwischen Zeilen in R basierend auf Spaltenwerten

df <- data.frame('controller_id' = c('X','X','X','X','X','X','Y','Y','Y','Y','Y','Y','Z','Z'), 
'user_id'=c('A','B','C','A','B','C','P','Q','R','P','Q','R',NA,NA), 
'mth_id'=c('1393','1393','1393','1398','1398','1398','1393','1393','1393','1398','1398','1398','1393','1398'), 
'col_val1' = c(5,4,6,3,1,10,12,15,18,13,19,1,5,2), 
'col_val2'=c(8,12,9,2,12,5,7,9,11,4,0,7,10,5)) 

> df 
    controller_id user_id mth_id col_val1 col_val2 
1    X  A 1393  5  8 
2    X  B 1393  4  12 
3    X  C 1393  6  9 
4    X  A 1398  3  2 
5    X  B 1398  1  12 
6    X  C 1398  10  5 
7    Y  P 1393  12  7 
8    Y  Q 1393  15  9 
9    Y  R 1393  18  11 
10    Y  P 1398  13  4 
11    Y  Q 1398  19  0 
12    Y  R 1398  1  7 
13    Z <NA> 1393  5  10 
14    Z <NA> 1398  2  5 

Was ich will, ist der Unterschied in der col_values ​​für jeden Controller_ID spezifische user_id, mth_id und Anzeige auf der Grundlage dieser col_values ​​nur zu berechnen, die zurückgegangen sind als die mth_id zugenommen hat.

Für zB: für controller_id = X haben wir 3 user_id als A, B, C für zwei verschiedene mth_ids. Code sollte für alle 3 users_id für mth_id 1398 und 1393 Unterschiede zwischen col_val1 berechnen und wenn die Differenz < 0, dann ist möchte ich eine Ausgabe wie

Col_val1 for controller_id 'X', user_id 'A' has decreased from 5 to 3 

Wenn für ein Controller_ID gegeben kein User_id zugeordnet ist, dann sollte es berechnen die Spaltenwertdifferenz zwischen controller_id selbst.

Im Idealfall möchte ich diese Ausgabe in einer Liste/Datenframe für die spätere Verwendung speichern. Der Code soll auch für ca. 900 Spalten im Datenrahmen vorhanden.

Ich Umwandlung alle Spalten außer Controller_ID, User_id, mth_id auf numerische Felder und dann für jedes User_id das Ergebnis bin ich der Berechnung (einzelne Spalte zu einer Zeit) mit ‚data.table

> df[,4:ncol(df)] <- sapply(df[,4:ncol(df)],as.numeric) 
> result_col1 <- setDT(df)[,val_diff := col_val1 - lag(col_val1,1L), by=user_id] 

> result_col1 
    controller_id user_id mth_id col_val1 col_val2 val_diff 
    1:    X  A 1393  5  8  NA 
    2:    X  B 1393  4  12  NA 
    3:    X  C 1393  6  9  NA 
    4:    X  A 1398  3  2  -2 
    5:    X  B 1398  1  12  -3 
    6:    X  C 1398  10  5  4 
    7:    Y  P 1393  12  7  NA 
    8:    Y  Q 1393  15  9  NA 
    9:    Y  R 1393  18  11  NA 
10:    Y  P 1398  13  4  1 
11:    Y  Q 1398  19  0  4 
12:    Y  R 1398  1  7  -17 
13:    Z  NA 1393  5  10  NA 
14:    Z  NA 1398  2  5  -3 

Ich möchte jedoch eine ähnliche Sache auf Controller_id Ebene erreichen. Ich kenne den Workflow wie - wähle eine Controller-ID - sehe, ob wir user_id drin haben oder nicht. Wenn wir das haben, vergleichen wir die Spaltenwerte user_id für 1393 und 1398 und sehen den Unterschied. Aber irgendwie kann ich das nicht programmieren.

Jede Hilfe würde sehr geschätzt werden.

+0

Sorry @agenis für nicht zu erwähnen, was ich früher versucht habe. Ich habe meine Fragen mit wenigen Schritten aktualisiert, die ich durchgeführt habe. –

+0

Wer kann mir dabei helfen? @ Hack-R –

Antwort

0

Whit Basis R:

usplit<-with(df,split(df,controller_id)) 

rsl<-lapply(usplit,function(dt){ 
    do.call("rbind",by(dt,factor(dt[,"user_id"],exclude = NULL),function(vt){ 
    n1=1:nrow(vt) 
    cbind(vt,rbind(NA,vt[n1[-1],4:5]-vt[n1[-length(n1)],4:5])) 
    })) 
}) 

do.call("rbind",rsl) 

> do.call("rbind",rsl) 
     controller_id user_id mth_id col_val1 col_val2 col_val1 col_val2 
X.A.1    X  A 1393  5  8  NA  NA 
X.A.4    X  A 1398  3  2  -2  -6 
X.B.2    X  B 1393  4  12  NA  NA 
X.B.5    X  B 1398  1  12  -3  0 
X.C.3    X  C 1393  6  9  NA  NA 
X.C.6    X  C 1398  10  5  4  -4 
Y.P.7    Y  P 1393  12  7  NA  NA 
Y.P.10    Y  P 1398  13  4  1  -3 
Y.Q.8    Y  Q 1393  15  9  NA  NA 
Y.Q.11    Y  Q 1398  19  0  4  -9 
Y.R.9    Y  R 1393  18  11  NA  NA 
Y.R.12    Y  R 1398  1  7  -17  -4 
Z.NA.13    Z <NA> 1393  5  10  NA  NA 
Z.NA.14    Z <NA> 1398  2  5  -3  -5 

Wenn das ist, was Sie wollen, sind die letzten beiden Spalten sind die Differentiale, als das Endergebnis ein data.frame ist einfach sein wird, zu ändern.

Verwandte Themen