Подтвердить что ты не робот

В R, как я могу вычислить процентную статистику по столбцу в фрейме данных? (функция таблицы, расширенная с процентами)

Это простой вопрос, но я не мог понять, как использовать prop.table для этого, и мне очень нужна эта функциональность.

У меня есть такие данные

> 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

И мне нужно знать процент курильщиков и некурящих Что-то вроде этого (уродливый код):

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

Есть ли лучший способ сделать это?

(еще лучше было бы сделать это на множестве столбцов (которые я перечисляю) и вывести несколько красиво отформатированный)  (например, курильщик, день и время)

4b9b3361

Ответ 1

Если это будет вам сжато, вам может понравиться:

prop.table(table(tips$smoker))

а затем масштабируйте на 100 и раунд, если хотите. Или больше, как ваш точный вывод:

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

Если вы хотите сделать это для нескольких столбцов, есть много разных направлений, на которые вы могли бы пойти, в зависимости от того, что ваши вкусы говорят вам, - это чистый вывод, но здесь один из вариантов:

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

Если вам не нравится складывать разные таблицы друг над другом, вы можете вырезать do.call и оставить их в списке.

Ответ 2

Ваш код не кажется таким уродливым для меня...
однако альтернативой (не намного лучше) может быть, например,

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

Я не уверен на 100%, но я думаю, что это делает то, что вы хотите использовать prop.table. Смотрите в основном последние 3 строки. Остальная часть кода просто создает поддельные данные.

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

Я сделал это для выполнения совокупных функций и подобных

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

Ответ 5

Вот версия Tidyverse:

library(tidyverse)
data(diamonds)

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

Или, если вы хотите удобную функцию:

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

Теперь вы можете сделать:

diamonds %>% getPercentages(cut)

или это:

df=diamonds %>% group_by(cut) %>% group_modify(~.x %>% getPercentages(clarity))
ggplot(df,aes(x=clarity,y=Perc))+geom_col()+facet_wrap(~cut)