web-dev-qa-db-fra.com

Créer un barplot empilé où chaque pile est réduite pour totaliser 100%

J'ai un data.frame comme ceci:

df <- read.csv(text = "ONE,TWO,THREE
                       23,234,324
                       34,534,12
                       56,324,124
                       34,234,124
                       123,534,654")

Je veux produire un tracé en pourcentage qui ressemble à ceci (créé dans LibreOffice Calc): enter image description here

Ainsi, les barres doivent être standardisées afin que toutes les piles aient la même hauteur et atteignent 100%. Jusqu'à présent, tout ce que j'ai pu obtenir, c'est un barplot empilé (pas pour cent), utilisant:

barplot(as.matrix(df))

De l'aide?

59
Julio Diaz

Voici une solution utilisant ce package ggplot (version 3.x) en plus de ce que vous avez obtenu jusqu'à présent.

Nous utilisons l'argument position de geom_bar Défini sur position = "fill". Vous pouvez également utiliser position = position_fill() si vous souhaitez utiliser les arguments de position_fill() (vjust et reverse).

Notez que vos données sont dans un format "large", alors que ggplot2 Exige qu'elles soient dans un format "long". Ainsi, nous devons d’abord gather les données.

library(ggplot2)
library(dplyr)
library(tidyr)

dat <- read.table(text = "    ONE TWO THREE
1   23  234 324
2   34  534 12
3   56  324 124
4   34  234 124
5   123 534 654",sep = "",header = TRUE)

# Add an id variable for the filled regions and reshape
datm <- dat %>% 
  mutate(ind = factor(row_number()) %>% 
  gather(variable, value, -ind)

ggplot(datm, aes(x = variable, y = value, fill = ind)) + 
    geom_bar(position = "fill",stat = "identity") +
    # or:
    # geom_bar(position = position_fill(), stat = "identity") 
    scale_y_continuous(labels = scales::percent_format())

enter image description here

100
joran

Chris Beeley a raison, vous n’avez besoin que des proportions par colonne. Utiliser vos données, c'est:

 your_matrix<-( 
               rbind(
                       c(23,234,324), 
                       c(34,534,12), 
                       c(56,324,124), 
                       c(34,234,124),
                       c(123,534,654)
                    )
                )

 barplot(prop.table(your_matrix, 2) )

Donne:

enter image description here

14
alemol

prop.table est un moyen sympathique d’obtenir des proportions de tables.

m <- matrix(1:4,2)

 m
     [,1] [,2]
[1,]    1    3
[2,]    2    4

Laisser une marge vide vous donne les proportions de la table entière

 prop.table(m, margin=NULL)
     [,1] [,2]
[1,]  0.1  0.3
[2,]  0.2  0.4

Donner 1 vous donne les proportions des rangées

 prop.table(m, 1)
      [,1]      [,2]
[1,] 0.2500000 0.7500000
[2,] 0.3333333 0.6666667

Et 2 est les proportions de la colonne

 prop.table(m, 2)
          [,1]      [,2]
[1,] 0.3333333 0.4285714
[2,] 0.6666667 0.5714286
13
Chris Beeley

Il vous suffit de diviser chaque élément par la somme des valeurs de sa colonne.

Cela devrait suffire:

data.perc <- apply(data, 2, function(x){x/sum(x)})

Notez que le deuxième paramètre indique à apply d'appliquer la fonction fournie aux colonnes (en appliquant 1, vous l'appliqueriez à des lignes). La fonction anonyme reçoit ensuite chaque colonne de données, une à la fois.

4
nico