2015-05-18 15 views
6

Ho dati che sembra seguente modo:Sottrarre

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 

voglio ottenere un tavolo con l'Total dello scorso Round (200) meno il Total di prima Round (100);

Ad esempio, per il partecipante 1, è 42 - 5 = 37.

L'output finale dovrebbe essere simile:

Participant Total 
1   37 
2  
40  -14 
+0

Grazie mille! Ero bloccato - ma ora ho trovato una soluzione (anche se meno elegante rispetto ai 2 proposti qui); expEnd = exp [exp $ Number_round == 200,] expBegin = exp [exp $ Number_round == 100,] Total_new = expEnd $ Totale - expBegin $ Totale – YefR

risposta

1

si può provare questo

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

Con R di base

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

né parimenti associati ad subset

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

O con data.table

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

o utilizzando binario unirsi

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

O con 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

Sto cercando di capire il tuo codice (che è intelligente, tra l'altro): cosa fa il 'Total [c (1L, .N)]'? Immagino di poter semplicemente fare riferimento a una colonna di ogni SD direttamente e di non dover digitare '.SD [, Total]' ma cosa fa il 'c (1L, .N)'? – grrgrrbla

+0

Seleziona solo il primo e l'ultimo valore, poiché sono sempre '100' e' 200' nell'esempio fornito. –

+0

ho capito dal test, ho ragione che 1L seleziona solo il primo elemento (usando 1L invece di 1 perché gli interi richiedono meno memoria di doppio/float) e. N dà il numero di elementi nell'elenco così da poterlo fare seleziona l'ultimo? quindi sarebbe come dire 'nrow (dt)'? – grrgrrbla

2

provare questo:

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

Tutti amano un po 'di sqldf, quindi non se la vostra esigenza è quella di uso applicare quindi provare questo:

In primo luogo alcuni dati di test:

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") 

uso successivo SQL per creare 2 colonne - una per il 100 rotonda e una per il 200 tondo e sottrarre loro

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) 
    ")