Получить процентное соотношение всех столбцов по общему количеству столбцов

#r #dplyr

#r #dplyr

Вопрос:

У меня есть фрейм данных, который выглядит следующим образом:

 Label       Jan       Feb       Mar
    A         1         2         3
    B         1         4         9
    C         1         4         3
 

Количество столбцов после «Метки» будет продолжать увеличиваться из месяца в месяц.

Я хочу создать вывод, который выглядит следующим образом:

 Label       Jan       Feb       Mar
    A      0.33      0.20      0.20
    B      0.33      0.40      0.40
    C      0.33      0.40      0.20
 

Ниже работает, но удаляет метку. Я могу привязать метку обратно, но интересно, есть ли более простой способ

 library(dplyr)
df[,-1] %>%
  mutate_all(funs(./sum(.))))
 

Ответ №1:

Мы можем использовать mutate_at/mutate_if или mutate с across (из dplyr версии >= 1.00 )

 library(dplyr)
df1 <- df %>%
     mutate(across(where(is.numeric), ~ ./sum(.)))
 

если мы используем более старую dplyr версию < 1.00

 df %>%
    mutate_if(is.numeric, ~ ./sum(.))
 

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

 df %>%
    mutate(across(where(is.numeric), ~ 
           formattable::percent(./sum(.))))
 

-вывод

 # Label    Jan    Feb    Mar
#1     A 33.33% 20.00% 20.00%
#2     B 33.33% 40.00% 60.00%
#3     C 33.33% 40.00% 20.00%
 

данные

 df - structure(list(Label = c("A", "B", "C"), Jan = c(1L, 1L, 1L), 
    Feb = c(2L, 4L, 4L), Mar = c(3L, 9L, 3L)),
    class = "data.frame", row.names = c(NA, 
-3L))
 

Комментарии:

1. Еще один вопрос, который является дополнением, но как мне сделать все эти значения в процентном формате. Я тоже могу задать отдельный вопрос.

2. Это так, я могу за 7 минут 🙂

3. не повезло с этим: ошибка в FUN(X[[i]], …) : Ошибка в FUN(X[[i]], …): неподдерживаемый тип для SparkDataFrame: formattablenumeric

4. results_percentage_format <- results %>% мутировать(по(где(является.числовым), ~ форматируемый::процент(./сумма(.))))

5. @nak5120 Хорошо, тогда, возможно, вам нужно paste0(100 * ./sum(.), "%")