【问题标题】:Function which outputs statistics for each variable combination为每个变量组合输出统计信息的函数
【发布时间】:2021-06-23 05:55:06
【问题描述】:

我想编写函数combinations_features(y, x),它遍历包含三个变量的所有组合,并为每个组合输出 r squared、adjusted r squared、AIC 和 BIC。

我的解决方案

combinations_features <- function(y, x) {
  
  # Define empty vectors to store statistics 
  feature_vec_1 <- feature_vec_2 <-
    feature_vec_3 <- feature_vec_4 <- c()
  
  # Obtaining all combinations containing three variables  
  comb_names <- utils::combn(colnames(x), 3)
  
  # For each combination obtain wanted statistics
  for (i in 1:ncol(comb_names)) {
    feature_vec_1 <- append(
      feature_vec_1, summary(lm(y ~ ., data = x[, comb_names[, i]]))$adj.r.squared
    )
    feature_vec_2 <- append(
      feature_vec_2, summary(lm(y ~ ., data = x[, comb_names[, i]]))$r.squared
    )
    feature_vec_3 <- append(
      feature_vec_3, AIC(lm(y ~ ., data = x[, comb_names[, i]]))
    )
    feature_vec_4 <- append(
      feature_vec_4, BIC(lm(y ~ ., data = x[, comb_names[, i]]))
    )
  }
  
  # Assign everything into data frame
  
  data.frame(
    "Adj R2" = feature_vec_1, "R2" = feature_vec_2,
    "AIC" = feature_vec_3, "BIC" = feature_vec_4
  )
}

让我们看看它是如何工作的 - 定义一些人工数据并将其提供给函数。

set.seed(42)
predictors <- data.frame(rnorm(100), runif(100), rexp(100), rpois(100, 1))
dependent <- rnorm(100)
    
> combinations_features(dependent, predictors)
         Adj.R2          R2      AIC      BIC
1 -0.0283756015 0.002787295 276.2726 289.2985
2  0.0000677269 0.030368705 273.4678 286.4937
3 -0.0011990695 0.029140296 273.5944 286.6203
4  0.0015404392 0.031796789 273.3204 286.3463

但是由于这两件事,我发现这段代码效率很低:

(1) 循环 - 我在矩阵列 comb_names 上循环它,我想知道它是否可以以某种方式省略

(2) 代码长度 - 这个代码很大!由于我为每个统计信息定义了feature_vec 并分别附加到它们。我想知道是否可以通过一个命令以某种方式完成分配给他们。

您能否告诉我是否可以应用 (1) 或 (2) 来改进我的代码?

【问题讨论】:

    标签: r function dataframe matrix vector


    【解决方案1】:

    与上面的想法相同,只需将lapply 直接应用于组合列表也可以:

    combinations_features <- function(y,x){
      do.call(rbind, lapply(utils::combn(colnames(x), 3, simplify=FALSE), 
        function(i){
          f1 <- lm(y ~ ., data=x[, i])
          data.frame(Adj.R2=summary(f1)$adj.r.squared,
                     R2=summary(f1)$r.squared,
                     AIC=AIC(f1), BIC=BIC(f1))
        }))
    }
    

    【讨论】:

      【解决方案2】:

      这个依赖于 tidyverse 的 bind_rows() 怎么样?我认为没有办法避免循环组合,但lapply 让一切都更整洁,恕我直言。

      combinations_features1 <- function(y, x) {
        comb_names <- utils::combn(colnames(x), 3)
        bind_rows(
          lapply(
            1:ncol(comb_names),
            function(z) {
              m <- lm(y ~ ., data = x[, comb_names[,z]])
              s <- summary(m)
              tibble(Adj.R2=s$adj.r.squared, R2=s$r.squared, AIC=AIC(m), BIC=BIC(m))
            }
          )
        ) 
      }
      
      combinations_features1(dependent, predictors)
      
      # A tibble: 4 x 4
            Adj.R2      R2   AIC   BIC
             <dbl>   <dbl> <dbl> <dbl>
      1 -0.0284    0.00279  276.  289.
      2  0.0000677 0.0304   273.  286.
      3 -0.00120   0.0291   274.  287.
      4  0.00154   0.0318   273.  286.
      

      bind_rows(),如果给定一个列表,则将列表的元素绑定到单个data.frame

      【讨论】:

        猜你喜欢
        • 2018-05-21
        • 2019-09-04
        • 1970-01-01
        • 2017-10-11
        • 2019-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多