#r #dplyr
Вопрос:
Я хочу рассчитать процент каждого столбца в фрейме данных и создать собственное имя для каждого из них.
Рассмотрим следующий код:
a<-structure(list(year = 2000:2005, Col1 = 1:6, Col2 = c(1L, 4L,
9L, 16L, 25L, 36L)), row.names = c(NA, -6L), class = "data.frame")
> a
year Col1 Col2
1 2000 1 1
2 2001 2 4
3 2002 3 9
4 2003 4 16
5 2004 5 25
6 2005 6 36
a<-a %>% rowwise() %>%
mutate(total = sum(across(starts_with("Col")), na.rm = T)) %>% data.frame()
a %>%
mutate_at(vars(starts_with("Col")) , funs(P = ./a$total * 100))
Результат выглядит следующим образом:
Как обработать имя двух последних столбцов(например, per_Col1 и per_Col2 вместо Col1_P и Col2_P, основной вопрос) ? Есть ли лучший способ(с помощью пакета dplyr) сделать это?( вместо того, чтобы вычислять сумму столбцов, а затем делить каждый из них на нее)
Ответ №1:
Вы можете использовать его вместе с аргументом .names:
a %>%
rowwise() %>%
mutate(total = sum(across(starts_with("Col")), na.rm = TRUE)) %>%
mutate(across(starts_with("Col") , ~./total * 100, .names = 'per_{col}')) %>%
ungroup()
что дает:
# A tibble: 6 x 6
year Col1 Col2 total per_Col1 per_Col2
<int> <int> <int> <int> <dbl> <dbl>
1 2000 1 1 2 50 50
2 2001 2 4 6 33.3 66.7
3 2002 3 9 12 25 75
4 2003 4 16 20 20 80
5 2004 5 25 30 16.7 83.3
6 2005 6 36 42 14.3 85.7
Ответ №2:
Вот несколько иной подход, использующий scales
:
library(scales)
library(dplyr)
a %>%
rowwise() %>%
mutate(Total = sum(c_across(Col1:Col2), na.rm = TRUE),
across(Col1:Col2, ~percent(./sum(Total), accuracy = 0.1), .names ="percent_{.col}")
)
выход
year Col1 Col2 Total percent_Col1 percent_Col2
<int> <int> <int> <int> <chr> <chr>
1 2000 1 1 2 50.0% 50.0%
2 2001 2 4 6 33.3% 66.7%
3 2002 3 9 12 25.0% 75.0%
4 2003 4 16 20 20.0% 80.0%
5 2004 5 25 30 16.7% 83.3%
6 2005 6 36 42 14.3% 85.7%
Ответ №3:
Мы можем использовать rowSums
это для векторизации
library(dplyr)
a %>%
mutate(total = rowSums(across(starts_with('Col'))),
across(starts_with('Col'), ~ ./total * 100, .names = 'per_{.col}'))
year Col1 Col2 total per_Col1 per_Col2
1 2000 1 1 2 50.00000 50.00000
2 2001 2 4 6 33.33333 66.66667
3 2002 3 9 12 25.00000 75.00000
4 2003 4 16 20 20.00000 80.00000
5 2004 5 25 30 16.66667 83.33333
6 2005 6 36 42 14.28571 85.71429