2015-05-18 35 views
6

Ich habe Daten, die die folgende Art und Weise aus:subtrahieren bestimmte Zeilen

Participant Round Total 
1  100  5 
1  101  8 
1  102  12 
1  200  42  
2  100  14 
2  101  71 
40  100  32 
40  101  27 
40  200  18 

Ich möchte einen Tisch bekommen mit dem Total der letzten Round (200) minus der Total der ersten Round (100);

Zum Beispiel - für Teilnehmer 1 - es ist 42 - 5 = 37.

sollte die endgültige Ausgabe wie folgt aussehen:

Participant Total 
1   37 
2  
40  -14 
+0

Vielen Dank! Ich steckte fest - aber jetzt fand ich eine Lösung (obwohl weniger elegant als die hier vorgeschlagenen 2); expEnd = exp [exp $ Zahl_rund == 200,] expBegin = exp [exp $ Zahl_rund == 100,] Total_new = expEnd $ Summe - expBegin $ Summe – YefR

Antwort

1

Sie diese mit

library(dplyr) 
group_by(df, Participant) %>% 
    filter(row_number()==1 | row_number()==max(row_number())) %>% 
    mutate(df = diff(Total)) %>% 
    select(Participant, df) %>% 
    unique() 
Source: local data frame [3 x 2] 
Groups: Participant 

    Participant df 
1   1 37 
2   2 57 
3   40 -14 
12

Mit Base R

aggregate(Total ~ Participant, df[df$Round %in% c(100, 200), ], diff) 
# Participant Total 
# 1   1 37 
# 2   2  
# 3   40 -14 

oder auf ähnliche Weise versuchen können subset

aggregate(Total ~ Participant, df, subset = Round %in% c(100, 200), diff) 

Oder mit data.table

library(data.table) ; 
setDT(df)[Round %in% c(100, 200), diff(Total), by = Participant] 
# Participant V1 
# 1:   1 37 
# 2:   40 -14 

Oder mit binären beitreten

setkey(setDT(df), Round) 
df[.(c(100, 200)), diff(Total), by = Participant] 
# Participant V1 
# 1:   1 37 
# 2:   40 -14 

Oder mit dplyr

library(dplyr) 
df %>% 
    group_by(Participant) %>% 
    filter(Round %in% c(100, 200)) %>% 
    summarise(Total = diff(Total)) 
# Source: local data table [2 x 2] 
# 
# Participant Total 
# 1   1 37 
# 2   40 -14 
+1

Ich versuche deinen Code zu verstehen (was übrigens clever ist): Was macht das 'Total [c (1L, .N)]'? Ich schätze, ich kann nur direkt auf eine Spalte jedes SD verweisen und muss nicht '.SD [, Total]' eingeben, aber was macht das 'c (1L, .N)'? – grrgrrbla

+0

Es wird nur der erste und der letzte Wert ausgewählt, da sie im angegebenen Beispiel immer '100' und' 200' sind. –

+0

Das habe ich aus dem Test verstanden, habe ich recht, dass 1L nur das erste Element auswählt (1L anstelle von 1 verwenden, weil ganze Zahlen weniger Speicher benötigen als doubles/floats) und .N gibt die Anzahl der Elemente in der Liste so an, wie ich kann wähle den letzten aus? also wäre es dasselbe wie "nrow (dt)" zu sagen? – grrgrrbla

2

versuchen Sie dies:

df <- read.table(header = TRUE, text = " 
Participant Round Total 
       1  100  5 
1  101  8 
1  102  12 
1  200  42  
2  100  14 
2  101  71 
2 200 80 
40  100  32 
40  101  27 
40  200  18") 

library(data.table) 
setDT(df)[ , .(Total = Total[Round == 200] - Total[Round == 100]), by = Participant] 
1

Jeder ein bisschen sqldf liebt, also, wenn Ihre Anforderung nicht ist dann zu verwenden, gelten versuchen, dieses:

Zunächst einige Testdaten:

df <- read.table(header = TRUE, text = " 
Participant Round Total 
       1  100  5 
1  101  8 
1  102  12 
1  200  42  
2  100  14 
2  101  71 
2 200 80 
40  100  32 
40  101  27 
40  200  18") 

Nächste Verwendung SQL zum Erstellen von 2 Spalten - eine für die 100 Runde und eine für die 200 Runde und subtrahieren sie

rolled <- sqldf(" 
    SELECT tab_a.Participant AS Participant 
     ,tab_b.Total_200 - tab_a.Total_100 AS Difference 
    FROM (
     SELECT Participant 
      ,Total AS Total_100 
     FROM df 
     WHERE Round = 100 
     ) tab_a 
    INNER JOIN (
     SELECT Participant 
      ,Total AS Total_200 
     FROM df 
     WHERE Round = 200 
     ) tab_b ON (tab_a.Participant = tab_b.Participant) 
    ") 
Verwandte Themen