2009-11-30 11 views
0

J'ai des données imbriquées pour les niveaux:de chiffres absolus à proportion (?!? Plyr R SAC) en deux données au niveau

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 

Maintenant, je veux simplement quelque chose - et je sens que je suis capable de faire c'est juste le mois dernier. Mais quelque chose a disparu dans ma tête: je veux des pourcentages (sans tenir compte NA), la somme à 100 pour chaque variable 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% 

je peux obtenir les totaux dont j'ai besoin avec

cast(L1~variable, data=melt(d, na.rm=T),sum) 

Mais je suppose que il devrait être possible de cuisiner une fonction qui me donne ce que je veux? J'ai essayé différentes approches avec moulage et plyr ... Mais il semble que noël a déjà apporté de nombreuses bières à mon cerveau frêle.

Toute aide sera appréciée, de même que toute abstention de downvote.

Thanx

ceci est mes données:

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

Je viens de voir ceci: http://stackoverflow.com/questions/1785320/calculating-percent-of-row-total-with-plyr - peut-être pertinente. Va maintenant aller au lit. J'espère aller plus loin demain. – Andreas

Répondre

2

Cela devrait faire l'affaire, je pense:

by(d, d$level1, function(x) cbind(x[,1:2], t(t(x[,-1:-2])/colSums(x[,-1:-2], na.rm=TRUE)))) 

Vous pouvez exécuter un do.call(rbind,...) sur que si vous voulez tout dans une donnée Cadre.

+0

C'est exactement ce que je cherchais! Merci beaucoup Jonathan. Pourquoi faut-il dupliquer en double ("t (t (x ..." – Andreas

+0

Comme la division se fait par ligne dans R, pour effectuer une normalisation par colonne, il faut d'abord la transposer de sorte que la normalisation soit en ligne , puis le transposer au format de colonne –

1

Si je comprends bien la question, vous avez les totaux, en utilisant:

totals <- cast(level1 ~ variable, data=melt(d, na.rm=T),sum) 

... et que vous voulez les convertir en pourcentages. (Notez que vous avez appelé la première colonne « L1 » dans votre texte de la question, mais la structure des appels de données la colonne « niveau 1 ».)

Aller des totaux des pourcentages est plus simple que vous le pensez.

prc <- 100 * totals[,-1]/colSums(totals[,-1]) 
rownames(prc) <- totals[,1] 
+0

Je suis désolé que je n'étais pas clair, c'était la solution de Jonathan que je voulais. – Andreas