varias En R, ¿cómo puedo calcular las estadísticas de porcentaje en una columna en un marco de datos?(función de tabla extendida con porcentajes)




varias graficas en r (4)

Esta es una pregunta simple, pero no pude averiguar cómo usar la tabla de prop. Para esto y necesito esta funcionalidad muy a menudo.

Tengo datos como este

> 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

Y necesito saber el porcentaje de fumadores y no fumadores. Algo como esto (código feo):

> #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
> 

¿Hay una mejor manera de hacer esto?

(incluso mejor sería hacer esto en un conjunto de columnas (que enumero) y tener un formato agradable) (por ejemplo, fumador, día y hora)

https://code.i-harness.com


Hice esto para cuando hago funciones agregadas y similares

per.fun <- function(x) {
    if(length(x)>1){
        denom <- length(x);
        num <- sum(x);
        percentage <- num/denom;
        percentage*100
        }
        else NA
    }

No estoy seguro al 100%, pero creo que esto hace lo que quiere usando una tabla de propiedades. Ver principalmente las últimas 3 líneas. El resto del código solo está creando datos falsos.

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)

Si lo que buscas es concisión, te puede gustar:

prop.table(table(tips$smoker))

y luego escalar por 100 y redondear si quieres. O más bien como su salida exacta:

tbl <- table(tips$smoker)
cbind(tbl,prop.table(tbl))

Si quisiera hacer esto para varias columnas, hay muchas direcciones diferentes que podría seguir dependiendo de lo que sus gustos le digan que es un resultado de apariencia limpia, pero aquí hay una opción:

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 no le gusta apilar las diferentes tablas una encima de la otra, puede do.call y dejarlas en una lista.


Tu código no me parece tan feo ...
sin embargo, una alternativa (no mucho mejor) podría ser, por ejemplo:

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




dataframe