C’est une question simple, mais je n’ai pas trouvé comment utiliser prop.table pour cela et j’ai besoin de cette fonctionnalité très souvent.
J'ai des données comme ça
> library(ggplot2)
> #sample data
> head(tips,3)
total_bill tip sex smoker day time size
1 17 1.0 Female No Sun Dinner 2
2 10 1.7 Male No Sun Dinner 3
3 21 3.5 Male No Sun Dinner 3
> #how often there is a non-smoker
> table(tips$smoker)
No Yes
151 93
> #how many subjects
> nrow(tips)
[1] 244
Et j'ai besoin de connaître le pourcentage de fumeurs par rapport aux non-fumeurs Quelque chose comme ceci (code laid):
> #percentage of smokers
> options(digits=2)
> transform(as.data.frame(table(tips$smoker)),percentage_column=Freq/nrow(tips)*100)
Var1 Freq percentage_column
1 No 151 62
2 Yes 93 38
>
Y a-t-il une meilleure manière de faire cela?
(Encore mieux, ce serait de le faire sur un ensemble de colonnes (que j’énumère) et d’avoir une sortie assez bien formatée) (par exemple, fumeur, jour et heure)
Si vous recherchez la concision, vous pourriez aimer:
prop.table(table(tips$smoker))
et puis balancez par 100 et arrondissez si vous aimez. Ou plus comme votre sortie exacte:
tbl <- table(tips$smoker)
cbind(tbl,prop.table(tbl))
Si vous voulez faire cela pour plusieurs colonnes, vous pouvez choisir un grand nombre de directions différentes en fonction de ce que vos goûts vous disent être une sortie nette, mais voici une option:
tblFun <- function(x){
tbl <- table(x)
res <- cbind(tbl,round(prop.table(tbl)*100,2))
colnames(res) <- c('Count','Percentage')
res
}
do.call(rbind,lapply(tips[3:6],tblFun))
Count Percentage
Female 87 35.66
Male 157 64.34
No 151 61.89
Yes 93 38.11
Fri 19 7.79
Sat 87 35.66
Sun 76 31.15
Thur 62 25.41
Dinner 176 72.13
Lunch 68 27.87
Si vous n'aimez pas empiler les différentes tables les unes sur les autres, vous pouvez abandonner le do.call
et les laisser dans une liste.
Votre code ne semble pas si moche pour moi ...
cependant, une alternative (pas beaucoup mieux) pourrait être par exemple. :
df <- data.frame(table(yn))
colnames(df) <- c('Smoker','Freq')
df$Perc <- df$Freq / sum(df$Freq) * 100
------------------
Smoker Freq Perc
1 No 19 47.5
2 Yes 21 52.5
Je ne suis pas certain à 100%, mais je pense que cela correspond à ce que vous voulez en utilisant prop.table. Voir principalement les 3 dernières lignes. Le reste du code ne fait que créer de fausses données.
set.seed(1234)
total_bill <- rnorm(50, 25, 3)
tip <- 0.15 * total_bill + rnorm(50, 0, 1)
sex <- rbinom(50, 1, 0.5)
smoker <- rbinom(50, 1, 0.3)
day <- ceiling(runif(50, 0,7))
time <- ceiling(runif(50, 0,3))
size <- 1 + rpois(50, 2)
my.data <- as.data.frame(cbind(total_bill, tip, sex, smoker, day, time, size))
my.data
my.table <- table(my.data$smoker)
my.prop <- prop.table(my.table)
cbind(my.table, my.prop)
Je l'ai fait pour quand faire des fonctions d'agrégation et similaire
per.fun <- function(x) {
if(length(x)>1){
denom <- length(x);
num <- sum(x);
percentage <- num/denom;
percentage*100
}
else NA
}