von absoluten Zahlen Anteil in zwei Level-Daten (R! SAC? plyr?)
Frage
Ich habe Daten verschachtelt, um Ebenen:
L1 L2 x1 x2 x3 x4
A This 20 14 12 15
A That 11 NA 8 16
A Bat Na 22 13 9
B This 10 9 11 6
B That 3 3 1 NA
B Bat 4 10 2 8
Jetzt möchte ich etwas einfach - und ich glaube, ich in der Lage gewesen diese erst im vergangenen Monat zu tun. Aber etwas hat sich in meinem Kopf vermisst: Ich Prozent wollen (ohne Berücksichtigung von NA), für jede Variable auf 100 Summieren in L1
L1 L2 x1 x2 x3 x4
A This 65% 39% 36% 38%
A That 35% 0% 24% 40%
A Bat 0% 61% 40% 22%
Ich kann die Summen bekomme ich mit
brauchencast(L1~variable, data=melt(d, na.rm=T),sum)
Aber ich denke, es sollte möglich sein, eine Funktion, um zu kochen, die mir gibt, was ich will? Ich habe versucht, verschiedene Ansätze mit den Darstellern und plyr ... Aber es Nähte Weihnachten schon zu viele Biere zu meinem gebrechlichen Gehirn gebracht hat.
Jede Hilfe wird geschätzt werden. - ebenso wie jeder Refrain von einem downvote
Thanx
Das ist meine Daten:
d <- structure(list(level1 = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L,
6L, 6L, 7L, 7L, 7L, 7L, 8L, 8L, 8L, 8L, 8L, 10L, 10L, 10L, 10L,
11L, 11L, 11L, 11L, 11L, 11L, 9L, 9L, 9L, 9L, 9L, 12L, 12L, 12L,
12L, 13L, 13L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 14L, 14L,
15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 16L, 16L, 17L, 17L,
17L, 17L, 17L, 18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L,
19L, 19L), .Label = c("a", "b", "c", "d", "e", "f", "g", "h",
"i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s"), class = "factor"),
level2 = structure(c(6L, 2L, 1L, 3L, 5L, 6L, 1L, 3L, 5L,
6L, 1L, 3L, 5L, 6L, 5L, 6L, 1L, 3L, 5L, 4L, 6L, 2L, 1L, 3L,
5L, 6L, 1L, 5L, 4L, 6L, 2L, 1L, 3L, 5L, 6L, 1L, 3L, 5L, 6L,
2L, 1L, 3L, 5L, 4L, 6L, 2L, 1L, 3L, 5L, 6L, 1L, 3L, 5L, 6L,
2L, 1L, 3L, 5L, 4L, 6L, 2L, 1L, 3L, 5L, 4L, 6L, 2L, 1L, 3L,
5L, 6L, 2L, 1L, 3L, 5L, 4L, 6L, 2L, 1L, 3L, 5L, 6L, 2L, 1L,
3L, 5L, 4L, 6L, 2L, 1L, 3L, 5L, 4L), .Label = c("This", "That",
"Phat", "Bat", "Man", "Hat"), class = "factor"), X2002 = c(28L,
9L, 17L, 8L, 95L, 18L, NA, NA, 36L, 40L, 15L, 10L, 71L, NA,
14L, 25L, 18L, NA, 56L, 5L, 29L, 5L, 13L, 8L, 65L, 23L, 8L,
34L, NA, 14L, 5L, 5L, NA, 51L, 18L, NA, 5L, 56L, 30L, 8L,
9L, 11L, 77L, 5L, 53L, 12L, 16L, 13L, 114L, 30L, 8L, NA,
52L, 38L, NA, 12L, 5L, 87L, 5L, 35L, NA, 10L, 6L, 92L, 10L,
41L, NA, 22L, 8L, 115L, 27L, 6L, 9L, NA, 47L, 9L, 29L, 6L,
11L, NA, 56L, 38L, 7L, 10L, NA, 93L, 6L, 22L, 9L, 9L, NA,
59L, 5L), X2003 = c(32L, NA, 16L, 9L, 76L, 10L, NA, 5L, 24L,
22L, 12L, 9L, 63L, 12L, 9L, 36L, 9L, 6L, 83L, 5L, 35L, NA,
12L, 8L, 82L, 19L, 5L, 53L, 5L, 10L, NA, 7L, NA, 35L, 15L,
6L, 6L, 40L, 30L, NA, 10L, 8L, 85L, 9L, 46L, NA, 14L, 9L,
106L, 24L, 6L, 7L, 56L, 33L, NA, 12L, 9L, 106L, NA, 37L,
7L, 11L, 8L, 79L, 5L, 54L, 5L, 10L, 6L, 100L, 25L, 9L, 5L,
6L, 49L, NA, 31L, NA, 13L, 10L, 79L, 46L, NA, 14L, NA, 82L,
5L, 21L, 7L, 11L, NA, 69L, NA), X2004 = c(35L, 6L, 13L, 8L,
82L, 12L, 5L, NA, 35L, 34L, 5L, 6L, 75L, 9L, 9L, 40L, 13L,
9L, 70L, NA, 41L, NA, 17L, 10L, 83L, 10L, 6L, 40L, NA, 18L,
NA, 6L, NA, 34L, 10L, NA, NA, 45L, 38L, 6L, 11L, NA, 74L,
NA, 45L, 5L, 12L, 9L, 131L, 34L, NA, NA, 64L, 28L, 5L, NA,
NA, 93L, NA, 32L, NA, 9L, 11L, 99L, NA, 40L, NA, 18L, 8L,
104L, 14L, NA, 13L, 6L, 67L, NA, 23L, NA, 6L, 8L, 85L, 49L,
NA, 19L, 7L, 102L, NA, 28L, 5L, 7L, 7L, 74L, NA), X2005 = c(36L,
NA, 20L, 10L, 93L, 22L, NA, NA, 35L, 38L, 13L, 9L, 99L, NA,
14L, 48L, 17L, 7L, 70L, NA, 35L, NA, 13L, 9L, 103L, 16L,
5L, 49L, NA, 12L, NA, 5L, 8L, 51L, 15L, 7L, 5L, 45L, 40L,
NA, 12L, 5L, 102L, NA, 40L, NA, 21L, 16L, 141L, 25L, 9L,
10L, 70L, 41L, NA, 10L, NA, 111L, NA, 37L, NA, 10L, 9L, 124L,
NA, 37L, NA, 12L, 12L, 124L, 32L, NA, 16L, 6L, 45L, NA, 33L,
NA, 8L, NA, 101L, 51L, NA, 19L, 5L, 117L, NA, 17L, NA, 11L,
5L, 73L, NA), X2006 = c(38L, NA, 22L, 13L, 103L, 15L, NA,
7L, 44L, 39L, 11L, 6L, 95L, NA, 15L, 53L, 16L, 9L, 89L, NA,
41L, NA, 12L, 13L, 87L, 30L, 6L, 43L, NA, 14L, NA, 6L, 5L,
50L, 19L, 5L, NA, 63L, 23L, NA, 6L, NA, 75L, NA, 38L, NA,
12L, 19L, 142L, 32L, 7L, 7L, 64L, 49L, NA, 13L, 12L, 114L,
NA, 48L, NA, 23L, 5L, 136L, NA, 52L, NA, 15L, 16L, 127L,
24L, NA, 6L, NA, 57L, NA, 32L, NA, NA, 13L, 96L, 20L, NA,
10L, 21L, 102L, NA, 31L, NA, 5L, 12L, 93L, NA)), .Names = c("level1",
"level2", "X2002", "X2003", "X2004", "X2005", "X2006"), row.names = c(NA,
-93L), class = "data.frame")
Lösung
Das sollte es tun ich denke:
by(d, d$level1, function(x) cbind(x[,1:2], t(t(x[,-1:-2]) / colSums(x[,-1:-2], na.rm=TRUE))))
Sie können eine do.call(rbind,...)
auf dem ausführen, wenn Sie alles in einem Datenrahmen werden sollen.
Andere Tipps
Als ich die Frage verstehen, haben Sie die Summen, mit:
totals <- cast(level1 ~ variable, data=melt(d, na.rm=T),sum)
... und Sie wollen, dass sie in Prozentsätze konvertieren. (Beachten Sie, dass Sie die erste Spalte „L1“ in Ihrer Frage Text genannt, aber die Datenstruktur ruft die Spalte „Ebene 1“.)
Wenn man von Summen Prozent ist einfacher als Sie denken.
prc <- 100 * totals[,-1] / colSums(totals[,-1])
rownames(prc) <- totals[,1]