Esta es una pregunta simple, pero yo no podía entender cómo el uso de la prop.tabla para esto y necesito esta funcionalidad muy a menudo.

Tengo los datos de 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 vs no fumadores
Algo como esto (feo código):

> #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 manera mejor de hacer esto?

(incluso mejor sería hacerlo en un conjunto de columnas (que yo enumerar) y tienen una salida algo bien formateada)
(por ejemplo, el fumador, el día y la hora)

  • consejos es un conjunto de datos dentro del paquete ggplot2
InformationsquelleAutor userJT | 2012-03-08

5 Comentarios

  1. 55

    Si es la concisión que buscas, te pueden gustar:

    prop.table(table(tips$smoker))

    y, a continuación, escala de 100 y vuelta si te gusta. O más como su exacta de salida:

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

    Si quería hacer esto por varias columnas, hay un montón de diferentes direcciones, usted podría ir dependiendo de lo que su gusto de decir es limpio buscando la salida, pero aquí es 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 te gusta la pila de las diferentes tablas en la parte superior de uno al otro, usted puede deshacerse de la do.call y dejarlos en una lista.

    • hmm.. yo no creo que sobre el «encadenamiento» de la mesa y la proposición.tabla así. ¿cómo se podía hacer para múltiples enumerados columnas…?
    • Editado con un posible ejemplo (pero hay un montón de diferentes maneras de acercarse a lo que usted describe).
    • puede dplyr agregar esa función (todos lo usamos todo el tiempo)
    • Creo que este código lee también la primera fila para el análisis. – Puedo female 22 45.83 Gender 1 2.08 male 25 52.08. ¿Cómo se puede saltar? – – Mis datos del separador es ficha \t. Acaba de hacer do.call(rbind,lapply(tips[-(1), 2:3],tblFun)).
  2. 10

    El código no parece tan feo para mí…

    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
  3. 4

    No estoy 100% seguro, pero creo que este hace lo que quiere, el uso de la prop.tabla. Ver sobre todo los últimos 3 líneas. El resto del código es sólo la creación de 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)
  4. 0

    Hice esto para cuando haciendo funciones de agregado y otros similares

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

    Aquí un tidyverse versión:

    library(tidyverse)
    data(diamonds)
    
    (as.data.frame(table(diamonds$cut)) %>% rename(Count=1,Freq=2) %>% mutate(Perc=100*Freq/sum(Freq)))

    O si desea una función práctica:

    getPercentages <- function(df, colName) {
      df.cnt <- df %>% select({{colName}}) %>% 
        table() %>%
        as.data.frame() %>% 
        rename({{colName}} :=1, Freq=2) %>% 
        mutate(Perc=100*Freq/sum(Freq))
    }

    Ahora usted puede hacer:

    diamonds %>% getPercentages(cut)

    o este:

    df=diamonds %>% group_by(cut) %>% group_modify(~.x %>% getPercentages(clarity))
    ggplot(df,aes(x=clarity,y=Perc))+geom_col()+facet_wrap(~cut)
    • Estoy recibiendo «Error: data debe ser un marco de datos, u otro objeto coercible por fortify(), no una lista de» mientras se ejecuta: pastebin.com/ZE58J3Ru Alguna manera de arreglarlo?
    • En la nueva versión de dplyr la funcionalidad de group_map ha cambiado ahora group_modify debe ser utilizado. He cambiado el ejemplo

Dejar respuesta

Please enter your comment!
Please enter your name here