【问题标题】:Automatic updating criteria for summarizing a data frame用于汇总数据框的自动更新标准
【发布时间】:2018-11-14 19:38:37
【问题描述】:

我有一个带有一堆标准的向量,我想用它来循环通过我的数据框来总结我的相关数据列。

我使用 dplyr 和管道重现了我的代码。它工作得很好,所以我将在下面解释我的挣扎。

我的代码:

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]]))})

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

【问题讨论】:

    标签: r loops dataframe criteria summarization


    【解决方案1】:

    这个函数可能是最不优雅的解决方案,但是如果我们保持相同的df 的列名(即criteria.namescriteria.datarelevant.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
    

    【讨论】:

      猜你喜欢
      • 2015-03-31
      • 2020-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-19
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      相关资源
      最近更新 更多