Group_by / суммировать по двум переменным внутри функции - PullRequest
0 голосов
/ 24 мая 2018

Я хотел бы написать функцию, которая суммирует предоставленные данные по некоторым заданным критериям, в данном случае по возрасту

В качестве примера приведены таблицы возраста пользователей и их статистики.

df <- data.frame('Age'=rep(18:25,2), 'X1'=10:17, 'X2'=28:35,'X4'=22:29)

Далее я определяю выходные столбцы, которые имеют отношение к анализу

output_columns <- c('Age', 'X1', 'X2', 'X3')

Эта функция вычисляет базовую сумму X1.X2 и X3 сгруппированы по возрасту.

aggr <- function(data, criteria, output_columns){
  k <- data %>% .[, colnames(.) %in% output_columns] %>%
    group_by_(.dots = criteria) %>%
    #summarise_each(funs(count), age) %>%
    summarize_if(is.numeric, sum)
  return (k)
}

Когда я называю это так

> e <- aggr(df, "Age", output_columns)
> e
# A tibble: 8 x 3
    Age    X1    X2
  <int> <int> <int>
1    18    20    56
2    19    22    58
3    20    24    60
4    21    26    62
5    22    28    64
6    23    30    66
7    24    32    68
8    25    34    70

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

> desired
  Age X1 X2 count
1  18 20 56     2
2  19 22 58     2
3  20 24 60     2
4  21 26 62     2
5  22 28 64     2
6  23 30 66     2
7  24 32 68     2
8  25 34 70     2

Я пробовал разные способы сделать это, например, tally (), sumrize_each и т. Д. Все они дают неправильные результаты.

Я считаю, что ихдолжен быть легкий и простой способ сделать это.Любая помощь приветствуется.

Ответы [ 3 ]

0 голосов
/ 24 мая 2018

Поскольку вы уже суммируете все переменные, вы можете просто добавить столбец всех 1 s перед функцией суммирования

aggr <- function(data, criteria, output_columns){ 
    data %>% 
      .[, colnames(.) %in% output_columns] %>%
      group_by_(.dots = criteria) %>%
      mutate(n = 1L) %>%
      summarize_if(is.numeric, sum)
}

# A tibble: 8 x 4
    Age    X1    X2     n
  <int> <int> <int> <int>
1    18    20    56     2
2    19    22    58     2
3    20    24    60     2
4    21    26    62     2
5    22    28    64     2
6    23    30    66     2
7    24    32    68     2
8    25    34    70     2
0 голосов
/ 24 мая 2018

В базе R вы можете сделать

aggr <- function(data, criteria, output_columns){
  ds <- data[, colnames(data) %in% output_columns]
  d <- aggregate(ds, by=list(criteria), function(x) c(sum(x), length(x)))
  "names<-"(do.call(data.frame, d)[, -c(2:3, 5)], c(names(ds), "n"))
}

> with(df, aggr(df, Age, output_columns))
  Age X1 X2 n
1  18 20 56 2
2  19 22 58 2
3  20 24 60 2
4  21 26 62 2
5  22 28 64 2
6  23 30 66 2
7  24 32 68 2
8  25 34 70 2
0 голосов
/ 24 мая 2018

Мы могли бы создать столбец 'count' до summarise_if

aggr<- function(data, criteria, output_columns){
                data %>% 
                   select(intersect(names(.), output_columns))%>%
                   group_by_at(criteria)%>%   
                   group_by(count = n(), add= TRUE) %>%                                
                   summarize_if(is.numeric,sum) %>%
                   select(setdiff(names(.), 'count'), count)                                     

    }




aggr(df,"Age",output_columns)
# A tibble: 8 x 4
# Groups:   Age [8]
#    Age    X1    X2 count
#  <int> <int> <int> <int>
#1    18    20    56     2
#2    19    22    58     2
#3    20    24    60     2
#4    21    26    62     2
#5    22    28    64     2
#6    23    30    66     2
#7    24    32    68     2
#8    25    34    70     2
...