2013-06-05 13 views
5

Domyślam się, że to jest łatwe przy użyciu ddply, ale jestem wciąż początkującym w R i nie mogę się z tym pogodzić.Jak obliczyć procent dla każdej komórki w ramce danych za pomocą ddply?

mam data.frame patrząc jak ten

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) 

ten sposób można przekształcić jedną zmienną w czasie, w procentach

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

Ale jak to zrobić ze wszystkimi zmiennymi (var1: var7) w data.frame za jednym pociągnięciem?

UWAGA: Przechodzi do funkcji, w której długość i liczba zmiennych różni się od czasu do czasu, a zatem kod powinien być na to wrażliwy.

góry dziękuję

Odpowiedz

4

Nie potrzeba wymyślnych opakowaniach. Będzie działać tak długo, jak chcesz to zrobić dla wszystkich oprócz pierwszej kolumny. Można dostosować warunki dla uwzględnionych kolumn, jeśli 2:ncol nie jest odpowiednie.

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

A skoro pytasz o plyr i dplyr jest ulepszona wersja ddply, oto jak chcesz zrobić z tym:

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

Konwersja danych na długim formacie, obliczyć proporcje i przełącz go z powrotem na szeroki. Dużo pisania dla tego, co Simon O'Hanlon okazuje się szybkim jednym liniowcem, ale metoda dplyr generalizuje ładnie do wszelkiego rodzaju obliczeń, które możesz chcieć zrobić.

+0

Dziękuję bardzo. działa idealnie – Einnor

+0

@Einnor jeśli to odpowiedział na twoje pytanie powinieneś * rozważyć * (przeczytaj - nie zobowiązany) akceptując go, aby pokazać, że to pytanie zostało wysłuchane. Zauważyłem, że nie zaakceptowałeś jeszcze żadnych odpowiedzi na swoje 6 pytań. Możesz przeczytać [** about **] (http://stackoverflow.com/about), aby zobaczyć, jak działa SO, aby pomóc Ci w pełni wykorzystać możliwości witryny. –

+0

@ Simon0101 Nie wiedziałem, że powinienem przyjąć odpowiedzi. Ale zrobi :) – Einnor

2

Może coś takiego może pomóc:

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

To działa również, dzięki :) – Einnor

+0

Można uprościć to nieco jak: 'data.frame (mydata [1], lapply (mydata [-1], funkcja (x) round (prop.table (x) * 100, 3))) ' – thelatemail

5

Wystarczy zmusić do matrix i użyć argumentu marginesu do prop.table tak:

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

Na przykład

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 

W twoim przykładzie wygląda to tak, jak myślałem, że to rownames jest w rzeczywistości kolumna wartości znaków. Aby użyć prop.table we wszystkich kolumnach oprócz tego pierwszego, możesz wykonać prop.table(df[,-1] , margin = 2).

+0

Dziękuję, to działa również – Einnor

Powiązane problemy