R: применить функцию к подмножествам на основе значения столбца

У меня есть фрейм данных с именем yield.df, который выглядит примерно так:

ID region income
1 rot 3700
2 ams 2500
3 utr 3300
4 utr 5300
5 utr 4400
6 ams 3100
8 ams 3000
9 rot 4000
10 rot 4400
12 rot 2000

Я хочу использовать функцию Gini для вычисления Коэффициент Джини для каждого региона. Если бы я хотел вычислить его для всего фрейма данных, не принимая во внимание регион, я бы сделал следующее:

library(DescTools)
Gini(income.df$income, n = rep(1, length(income.df$income)), unbiased = TRUE, conf.level = NA, R = 1000, type = "bca", na.rm = TRUE)

Есть ли способ сделать это для каждого региона в кадре данных? Так что же в данном случае для «гниль», «утр» и «амс»? Обратите внимание, что для функции Джини также требуется длина вектора (которая будет равна 4, 3 и 3 для трех областей соответственно). Я подозреваю, что что-то вроде lapply может это сделать, но я не мог понять, как автоматически передавать эти длины внутри функции (мой фактический фрейм данных намного больше, поэтому вручную это не вариант).


person Abdel    schedule 07.08.2018    source источник


Ответы (1)


Использование базы R:

library(DescTools)
lapply(split(df,df$region), 
       function(x) (Gini(x$income, n = rep(1, length(x$income)), unbiased = TRUE, 
                         conf.level = NA, R = 1000, type = "bca", na.rm = TRUE)))

Использование Tidyverse:

library(tidyverse)
library(DescTools)
df %>% group_by(region) %>% nest() %>% 
       mutate(gini_coef = map(data, ~Gini(.x$income, n = rep(1, length(.x$income)), 
              unbiased = TRUE, conf.level = NA, R = 1000, type = "bca", na.rm = TRUE))) %>%
       select(-data) %>% unnest() %>% left_join(df)


Joining, by = "region"
# A tibble: 10 x 4
region   gini_coef ID  income
<fct>    <dbl>   <int>  <int>
1 rot    0.177      1   3700
2 rot    0.177      9   4000
3 rot    0.177     10   4400
4 rot    0.177     12   2000
5 ams    0.0698     2   2500
6 ams    0.0698     6   3100
7 ams    0.0698     8   3000
8 utr    0.154      3   3300
9 utr    0.154      4   5300
10 utr    0.154      5   4400

Данные

 df <- read.table(text="  
            ID region income
             1 rot 3700
             2 ams 2500
             3 utr 3300
             4 utr 5300
             5 utr 4400
             6 ams 3100
             8 ams 3000
             9 rot 4000
             10 rot 4400
             12 rot 2000
             ",header=T)
person A. Suliman    schedule 07.08.2018