من الأعداد المطلقة للنسبة في البيانات مستويين (R! SAC؟ plyr؟)
سؤال
ولدي البيانات المتداخلة في لمستويات:
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
والآن أريد شيئا ببساطة - وأنا أشعر أنني تمكنت من القيام بذلك الشهر الماضي فقط. ولكن شيئا ما قد ذهب في عداد المفقودين في رأسي: أريد النسب المئوية (تجاهل NA)، ملخصا إلى 100 لكل متغير في 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%
ويمكنني الحصول على مجاميع أحتاج مع
cast(L1~variable, data=melt(d, na.rm=T),sum)
ولكن أعتقد أنه ينبغي أن يكون من الممكن سلق وظيفة أن يعطيني ما أريد؟ حاولت نهج مختلف مع المدلى بها وplyr ... ولكن طبقات عيد الميلاد أدى بالفعل إلى العديد من البيرة إلى ذهني واهية.
وسيتم تقدير أي مساعدة - كذلك أي الامتناع من downvote
وثنإكس
وهذا هو البيانات الخاصة بي:
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")
المحلول
وهذا ينبغي أن تفعل خدعة أعتقد:
by(d, d$level1, function(x) cbind(x[,1:2], t(t(x[,-1:-2]) / colSums(x[,-1:-2], na.rm=TRUE))))
ويمكنك تشغيل do.call(rbind,...)
على أنه إذا كنت تريد كل شيء في إطار بيانات واحدة.
نصائح أخرى
وكما فهمت السؤال، لديك المجاميع، وذلك باستخدام:
totals <- cast(level1 ~ variable, data=melt(d, na.rm=T),sum)
... وتريد تحويلها إلى نسب مئوية. (لاحظ أنك يسمى العمود الأول "L1" في نص السؤال، ولكن بنية البيانات يدعو عمود "level1".)
والانتقال من مجاميع النسب هو أكثر وضوحا مما كنت اعتقد.
prc <- 100 * totals[,-1] / colSums(totals[,-1])
rownames(prc) <- totals[,1]