2016-06-29 34 views
3

Ich arbeite an einem Datensatz, der die Summe für jede FMCG-Kategorie und ihre Verteilung der Verkäufe nach jedem Hauptkanal enthält, wie in den Spalten angegeben. Der Extrakt ist als untenBerechnen von Prozentsätzen der Gesamtsumme in gleichen Intervallen in einem Datensatz in R

CTY totsal MTsal GTsal Othsal totsal MTsal GTsal Othsal 
    food food food food deo  deo deo  deo 
Arg 47313 19620 15052 12641 178  113 41  24 
Aus 143140 85172 4634 53334 459  438 5  16 
Bel 125399 82966 7818 34614 424  229 5  190 

In meinen Ausgangsdaten gesetzt Ich mag auf Aktien der gesamten Kategoriegruppe berechnen, die in jedem 4. Spalte ist z.B. totsal Essen und totsal Deo. SO müssen die Anteile für diese 1 sein und die Anteile für die Kanäle, die sich zur Summe addieren, müssen ihre jeweiligen Werte sein. Das Beispiel Ausgabe ich bin auf der Suche ist:

CTY totshar MTshar GTshar Othshar totshar MTshar GTshar Othshar 
    food food food food deo  deo deo  deo 
Arg 1  0.4  0.3  0.3  1.0  0.6 0.2  0.1 
Aus 1  0.6  0.0  0.4  1.0  1.0 0.0  0.0 
Bel 1  0.7  0.1  0.3  1.0  0.5 0.0  0.4 

Das obige Beispiel ist ein Extrakt, und ich brauche Flexibilität zu übernehmen, so viele Kategorien und Länder umfasst ich kann.

+0

Können Sie einen Auszug Ihres Datenrahmens posten? (nur 'dput (Kopf (df))') – RoyalTS

+0

Hi nicht sicher, was du meinst. Das Beispiel, das ich gezeigt habe, ist ein Auszug. Hier gibt es 8 Spalten, in denen der 1. die Summe für die Spalte Nr. 2 3 4 und 5 ist die Summe für Spalte 6 7 8. Dieser Fortschritt setzt sich für den gesamten Datensatz fort. – user36176

Antwort

4

Sie können so etwas tun. Zuerst habe ich kopiert & Ihre Daten eingefügt:

I
d <- read.table("clipboard",header=T) 
d 
    CTY totsal MTsal GTsal Othsal totsal.1 MTsal.1 GTsal.1 Othsal.1 
1 <NA> food food food food  deo  deo  deo  deo 
2 Arg 47313 19620 15052 12641  178  113  41  24 
3 Aus 143140 85172 4634 53334  459  438  5  16 
4 Bel 125399 82966 7818 34614  424  229  5  190 

dann die Zahlen in einen numerischen Matrix

m <- data.frame(d[-1, -1]) 
m <- t(apply(m, 1, function(x) as.numeric(as.character(x)))) 
m 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] 
2 47313 19620 15052 12641 178 113 41 24 
3 143140 85172 4634 53334 459 438 5 16 
4 125399 82966 7818 34614 424 229 5 190 

ich für die gesamten Spalten gesucht transformiert grep verwenden, und erstellt einen Index gr für die Spaltengruppen . Beachten Sie, dass die total Spalte immer die erste Spalte der Gruppe sein muss. Die Gesamtzahl der Gruppenwerte kann variieren.

gr_total <- grep("tot", colnames(d)[-1]) 
gr <- sort(rep(gr_total, 4)) 

I verwendet sapply den Prozentsatz pro Gruppe zu berechnen, und das Ergebnis mit der matrix Funtion transformieren. Die Sapply-Funktion "durchläuft" alle durch die grep Suche gefundenen Gruppen. Innerhalb der function(x, y, z) Unterteilung alle Spalten, die zu der Gruppe gehören. Hier für die erste m[, gr == gr_total[1]]. Da R für vektorisierte Prozesse optimiert ist, können Sie einen Vektor/eine Matrix durch einen Vektor teilen. Versuchen Sie m[, gr == gr_total[1]]/m[ , gr_total[1]]. Für die matrix() Funktion sehen Sie bitte ?matrix und überprüfen Sie den sapply Ausgang.

matrix(sapply(gr_total, function(x, y, z) z[, y==x]/z[, x], gr, m), nrow(m), ncol(m), byrow = FALSE) 
    [,1]  [,2]  [,3]  [,4] [,5]  [,6]  [,7]  [,8] 
[1,] 1 0.4146852 0.31813666 0.2671782 1 0.6348315 0.23033708 0.13483146 
[2,] 1 0.5950258 0.03237390 0.3726003 1 0.9542484 0.01089325 0.03485839 
[3,] 1 0.6616161 0.06234499 0.2760309 1 0.5400943 0.01179245 0.44811321 

können Sie verwenden, um die round Funktion für eine Stelle runden. Angenommen, Sie haben das Ergebnis unter m1round(m1, 1) gespeichert. Spaltennamen können durch colnames(m1) <- colnames(d)[-1] ersetzt werden. Zum Hinzufügen von Spalten und Zeilen siehe rbind und cbind.

+0

Funktioniert perfekt. Können Sie den letzten Sapply- und Matrix-Code ein wenig im Detail erklären? Auch bekomme ich die Spaltennamen nicht als den ursprünglichen Datensatz. Ich bekomme sie als V1 V2 usw., gibt es eine Möglichkeit, sie zurück zu bekommen oder diese V1 V2 durch die ursprünglichen Spaltennamen zu ersetzen? – user36176

+1

@ user36176 meine Änderungen sehen. – Jimbou