Dans R, Comment puis-je calculer des statistiques en pourcentage sur une colonne dans un dataframe? (fonction de tableau étendue avec des pourcentages)
C'est une question simple mais je ne pouvais pas comprendre comment utiliser prop.table pour cela et j'ai besoin de cette fonctionnalité très très souvent.
J'ai des données comme ceci
> 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 savoir pourcentage de fumeurs vs 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 façon de le faire?
(encore mieux ce serait de le faire sur un ensemble de colonnes (que j'énumère) et avoir une sortie un peu bien formatée) (par exemple, le tabagisme, le jour et l' temps)
4 réponses
Si c'est la concision que vous recherchez, vous aimerez peut-être:
prop.table(table(tips$smoker))
Et puis échelle par 100 et rond si vous le souhaitez. Ou plus comme votre sortie exacte:
tbl <- table(tips$smoker)
cbind(tbl,prop.table(tbl))
Si vous vouliez le faire pour plusieurs colonnes, il y a beaucoup de directions différentes que vous pourriez aller en fonction de ce que vos goûts vous disent est une sortie propre, 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 les do.call
et les laisser dans une liste.
Votre code ne me semble pas si laid...
cependant, une autre (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 sûr à 100%, mais je pense que cela fait ce que vous voulez en utilisant prop.table. Voir la plupart du temps 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)
J'ai fait cela pour en faisant des fonctions d'agrégation et similaires
per.fun <- function(x) {
if(length(x)>1){
denom <- length(x);
num <- sum(x);
percentage <- num/denom;
percentage*100
}
else NA
}