2013-06-05 15 views
5

La mia ipotesi è che sia facile usare ddply ma sono ancora un principiante di R e non riesco a capirlo.Come calcolare la percentuale per ogni cella in un dataframe usando ddply?

Ho un data.frame cercando in questo

txt <- "label var1 var2 var3 var4 var5 var6 var7 
lab1 401 80 57 125 118 182 83 
lab2 72 192 80 224 182 187 178 
lab3 7 152 134 104 105 80 130 
lab4 3 58 210 30 78 33 87 
lab5 1 2 3 1 1 2 6" 

mydata <- read.table(textConnection(txt), sep = " ", header = TRUE) 

facendo questo posso trasformare una variabile in un momento in percentuale

mydata$var1 <- round(prop.table(mydata$var1),3)*100 

Ma come si fa con tutte le variabili (var1: var7) in un data.frame in un colpo solo?

NOTA: sta entrando in una funzione, in cui la lunghezza e il numero di variabili differiscono di volta in volta, e quindi il codice dovrebbe essere sensibile a questo.

Grazie in anticipo

risposta

4

Non c'è bisogno di pacchetti speciali. Questo funzionerà finché vuoi farlo a tutti tranne la prima colonna. È possibile adattare le condizioni per le colonne incluse se 2:ncol non è appropriato.

t(round(t(mydata[, 2:ncol(mydata)])/colSums(mydata[, 2:ncol(mydata)]) * 100, 3)) 

E, dal momento che hai chiesto plyr e dplyr è la versione migliorata del ddply, ecco come si farebbe con quella:

require(dplyr) 
require(reshape2) 

mydata %>% melt(id.vars = "label") %>% 
    group_by(variable) %>% 
    mutate(prop = round(value/sum(value) * 100, 3)) %>% 
    dplyr::select(-value) %>% 
    dcast(label ~ variable, fun.aggregate = sum, value.var = "prop") 

Convertire i dati in formato lungo, calcolare le proporzioni e riaccenderlo in largo. Un bel po 'di battitura per quello che Simon O'Hanlon mostra per essere un one-liner veloce, ma il metodo dplyr generalizza bene a qualunque tipo di calcolo si possa desiderare.

+0

Grazie mille. funziona perfettamente – Einnor

+0

@Einnor se questo ha risposto alla tua domanda dovresti * considerare * (leggi - non obbligato) accettarlo per mostrare che questa domanda ha avuto risposta. Noto che non hai ancora accettato alcuna risposta alle tue 6 domande. Puoi leggere il [** circa **] (http://stackoverflow.com/about) per vedere come funziona SO per aiutarti a ottenere il massimo dal sito. –

+0

@ Simon0101 Non sapevo che avrei dovuto accettare le risposte. Ma lo farà :) – Einnor

2

Forse qualcosa di simile questo può aiutare:

cbind(label=mydat[,1],as.data.frame(apply(mydat[,-1], 2, function(col) round(prop.table(col),3)*100))) 
+0

Funziona anche così, grazie :) – Einnor

+0

Puoi semplificare leggermente questo come: 'data.frame (mydata [1], lapply (mydata [-1], funzione (x) round (prop.table (x) * 100, 3))) ' – thelatemail

5

Basta costringere ad un matrix e utilizzare l'argomento margine per prop.table in questo modo:

round(prop.table(as.matrix(df),2) * 100 , 3) 

Per esempio

set.seed(123) 
df <- data.frame(matrix(sample(4 , 12 , repl=TRUE) , 3)) 
df 
# X1 X2 X3 X4 
#1 2 4 3 2 
#2 4 4 4 4 
#3 2 1 3 2 
round(prop.table(as.matrix(df),2) * 100 , 3) 
# X1  X2 X3 X4 
#[1,] 25 44.444 30 25 
#[2,] 50 44.444 40 50 
#[3,] 25 11.111 30 25 

Nel tuo esempio sembra che quello che pensavo fosse che i rownames fossero in realtà a colonna di valori di carattere. Per utilizzare prop.table su tutte le colonne tranne questa prima, è possibile eseguire prop.table(df[,-1] , margin = 2).

+0

Grazie, anche questo funziona – Einnor

Problemi correlati