自动更新标准以汇总数据框

时间:2018-11-14 19:38:37

标签: r loops dataframe criteria summarization

我有一个带有一堆条件的向量,我想用它来循环浏览我的数据框,以汇总相关的数据列。

我使用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]]))})

我想要的是找到一种优雅的方法来获取用户提供给我的值,并使用它们来自动计算摘要,而无需手动编辑代码。谢谢!

1 个答案:

答案 0 :(得分:0)

此功能可能是最不优雅的解决方案,但是如果我们保留相同的df的列名(即criteria.namescriteria.datarelevant.data),它就可以工作: / p>

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