Критерии автоматического обновления для суммирования фрейма данных - PullRequest
0 голосов
/ 14 ноября 2018

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

Я воспроизвожу ниже мой код, используя dplyr и pipe.Это работает отлично, поэтому я объясню мою борьбу ниже.

Мой код:

c1 <- c(0.5,0.5,0.5,1,1,1,2,2,2,2.5,2.5,2,3,3,4,4,4.4,4.5,4.5,5,5.5,6,7,7,8,8.5,9,9.5)
c2 <- c(12,10,40,4,12,7,3,2,1,4,8,10,10,7,7,4,4,4,5,5,6,15,15,25,4,4,7,18)
c3 <- rep(c("AA","BB","CC","DD"), 7)

df <- data.frame(criteria.names = c3, criteria.data = c1, relevant.data = c2,
 stringsAsFactors = FALSE)

user.criteria <- c(0,2,3,5,7,10)


summarised.data <- df %>%
  group_by(criteria.names) %>%
    summarise(class1 = sum(relevant.data[criteria.data >= 0 & criteria.data < 2]),
              class2 = sum(relevant.data[criteria.data >= 2 & criteria.data < 3]),
              class3 = sum(relevant.data[criteria.data >= 3 & criteria.data < 5]),
              class4 = sum(relevant.data[criteria.data >= 5 & criteria.data < 7]),
              class5 = sum(relevant.data[criteria.data >= 7 & criteria.data < 10]))

Вот мой ожидаемый результат:

 summarised.data
# A tibble: 4 x 6
  criteria.names class1 class2 class3 class4 class5
  <chr>           <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
1 AA                 24      1     14      6      4
2 BB                 17      4     11     15      4
3 CC                 40     11     12      0     22
4 DD                  4     12      4      5     43

МОЯ ПРОБЛЕМА: мой вектор "user.criteria", значения которого я использую в своемсуммирование, будет происходить через пользовательский ввод, так что нет никакой гарантии, что они фактически предоставят мне 2,3,5,7,10 значения (0 всегда будет там по умолчанию), я явно вставил вмои расчеты.Я пытался использовать функции семейства apply (apply, sapply, lapply, mapply) и adply (пакет plyr), но до сих пор мне не удалось решить эту проблему.Я стараюсь избегать использования явных циклов в R, поскольку база данных, с которой я работаю, довольно велика.

Ниже приведен пример моего некорректного кода:

summarised.try <- 1:(length(user.criteria)-1) %>%
  adply(1,function(x){
   df %>%
      group_by(criteria.names) %>%
      summarise(class = sum(relevant.data[criteria.data >=user.criteria[x]
  & criteria.data < user.criteria[x+1]]))})

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

1 Ответ

0 голосов
/ 23 ноября 2018

Эта функция может быть наименее элегантным решением, однако она работает, если мы сохраняем одинаковые имена столбцов df (т.е. criteria.names, criteria.data, relevant.data):

library(dplyr)

classifier <- function(criteria, df){

  classified_columns = list()

  for(i in 1:length(criteria) ){

    tmp_class = vector("numeric")

    for( ii in unique(df$criteria.names) ){

      tmp_df = df[df$criteria.names == ii,] 

      if ( i + 1 <= length(criteria)  ){

        tmp_df %>%
          summarise(n = relevant.data[criteria.data >= criteria[i] & criteria.data < criteria[i + 1]] %>% 
                      sum() )  %>%
          .$n %>%
          append(x = tmp_class, values = .) -> tmp_class
      }
    } 

    if( length(tmp_class) > 0 ){

      classified_columns[[paste("class", i, sep = "")]] = tmp_class 
    }       
  }

  data.frame(criteria.names = unique(df$criteria.names),
             as.data.frame(classified_columns)) %>% 
    return(.)
}

Функция тестирования:

classifier(criteria = user.criteria, df = df)

Выход:

   criteria.names class1 class2 class3 class4 class5
1             AA     24      1     14      6      4
2             BB     17      4     11     15      4
3             CC     40     11     12      0     22
4             DD      4     12      4      5     43
...