2015-07-16 8 views
5

Ecco il mio dati:R: calcolare il quoziente di 2 colonne per ID

ID  nb  ecart  
ID1  3  NA 
ID1  3  0  
ID1  3  1.5 
ID2  2  NA 
ID2  2  648 
ID3  4  NA 
ID3  4  0 
ID3  4  0 
ID3  4  7 

voglio calcolare la percentuale del numero di Ecart, che == "0" per ogni ID.

nb è la variabile che mostra il numero di righe per ciascun ID.

Il risultato exceped:

ID  nb  ecart percentage 
ID1  3  NA  NA 
ID1  3  0  1/3 
ID1  3  1.5  NA 
ID2  2  NA  NA 
ID2  2  648  NA 
ID3  4  NA  NA 
ID3  4  0  2/4 
ID3  4  0  2/4 
ID3  4  7   NA 

La speranza di ottenere la vostra risposta presto! Grazie!

+0

Possibile duplicato di [questo] (http://stackoverflow.com/questions/31439306/how-to-make-an-average-of-a-variable-assigned-to-individuals-within-a -category/31439514 # 31439514); inoltre, l'output è chiaro perché 'ecart == 0' è 2/4 per 'ID3' – SabDeM

+0

@SabDeM che ho aggiornato. Grazie per la tua osservazione. – velvetrock

+0

Vuoi davvero '1/3' o vuoi' .333' – MichaelChirico

risposta

8

Un rapido ed efficiente data.table soluzione

library(data.table) 
setDT(df)[ecart == 0L, percentage := round(.N/nb, 2L), by = ID] 
#  ID nb ecart percentage 
# 1: ID1 3 NA   NA 
# 2: ID1 3 0.0  0.33 
# 3: ID1 3 1.5   NA 
# 4: ID2 2 NA   NA 
# 5: ID2 2 648.0   NA 
# 6: ID3 4 NA   NA 
# 7: ID3 4 0.0  0.50 
# 8: ID3 4 0.0  0.50 
# 9: ID3 4 7.0   NA 

Come funziona: Questo modificherà i valori di percentagecon riferimento solo quando ecart == 0L calcolando la dimensione del sottogruppo (utilizzando .N) diviso per nb


Or (come commentato da @CathG), se si desidera una stampa di carattere piuttosto invece di un valore numerico, si può fare

setDT(df)[ecart == 0L, percentage := paste0(.N, "/", nb), by = ID] 

O se si preferisce utilizzare un binario unirsi

setkey(setDT(df), ecart)[.(0L), percentage := paste0(.N, "/", nb), by = ID] 
+0

hai assunto' nb' è il pieno '.N', che immagino sia giusto ... – MichaelChirico

+0

@MichaelChirico Non ho" assunto " questo è ciò che ha detto l'OP stesso. E cito: "* nb è la variabile che mostra il numero di righe per ogni ID *". –

+1

molto vero! Giuro che sono cieco. – MichaelChirico

3

Ecco una risposta dplyr.

library(dplyr) 

data %>% 
    group_by(ID) %>% 
    mutate(percentage = 
     ifelse(is.na(ecart), 
       NA, 
       sum(ecart == 0, na.rm = TRUE)/n()))