【问题标题】:Statistics of multiple similarly named columns多个类似名称的列的统计信息
【发布时间】:2017-06-17 17:12:00
【问题描述】:

我有一个包含多个列的庞大数据集,例如x1x2x3......x25y1y2y3...... y50z1z2.......z10 等看起来像这样:

x1  x2  x3  x4  y1  y2  y3  
1   2   1   2   1   1   2   
2   1   1   1   3   1   1
1   2   2   1   1   2   1

我想要的是:

x_mean  x_min  x_max  x_mad  y_mean  y_min  y_max  y_mad
  1.5     1      2     0.74    2       1      2      0 
  1.25    1      2       0     2       1      2      0 
  1.5     1      2     0.74    2       1      2      0 

基本上,我需要计算minmaxmad(中值绝对偏差)和mean

> x_mean = (x1+x2+x3+x4)/4 = (1+2+1+2)/4 

对于其他行和其他统计数据也是如此。我如何在 R 中做到这一点,最好是在 dplyr 中?

【问题讨论】:

    标签: r statistics dplyr


    【解决方案1】:

    通常您可以使用summarise 的作用域变体,例如summarise_all,在它们的funs 辅助函数中可以接受任意数量的汇总函数。在您的情况下,您应该首先重塑为长格式,以使您的数据tidy(此处将观察结果从列移动到行),从而使您的分析更简单:

    library(tidyverse)
    
    df <- read.table(text = 'x1  x2  x3  x4  y1  y2  y3  
    1   2   1   2   1   1   2   
    2   1   1   1   3   1   1
    1   2   2   1   1   2   1', head = TRUE)
    
    df_tidy <- df %>% 
        mutate(row = row_number()) %>%       # keep position info
        gather(var, val, -row) %>%           # reshape to long
        mutate(var = sub('\\d', '', var))    # extract letters from former colnames
    
    df_summary <- df_tidy %>%
        group_by(var, row) %>%                # group by variable and original row
        summarise_all(funs(min, max, mad))    # summarize with various functions
    
    df_summary
    #> # A tibble: 6 x 5
    #> # Groups:   var [?]
    #>     var   row   min   max    mad
    #>   <chr> <int> <dbl> <dbl>  <dbl>
    #> 1     x     1     1     2 0.7413
    #> 2     x     2     1     2 0.0000
    #> 3     x     3     1     2 0.7413
    #> 4     y     1     1     2 0.0000
    #> 5     y     2     1     3 0.0000
    #> 6     y     3     1     2 0.0000
    

    如果您愿意,您可以将其重新调整为宽,但出于任何保存演示目的,我建议您不要这样做。

    【讨论】:

      【解决方案2】:

      不像tidyverse 方法那样优雅,但仍然是一个基本的 R 选项,

      #create a function to do whatever calculations needed,
      f1 <- function(d){
        mean1 <- rowMeans(d)
        min1 <- do.call(pmin, d)
        max1 <- do.call(pmax, d)
        mad1 <- apply(d, 1, mad)
        return(data.frame(mean1, min1, max1, mad1))
      }
      
      #apply it to your data frame based on the unique name letters,
      ind <- unique(sub('\\d+', '', names(df)))
      setNames(lapply(ind, function(i) f1(df[grepl(i, names(df))])), ind)
      #$x
      #  mean1 min1 max1   mad1
      #1  1.50    1    2 0.7413
      #2  1.25    1    2 0.0000
      #3  1.50    1    2 0.7413
      
      #$y
      #     mean1 min1 max1 mad1
      #1 1.333333    1    2    0
      #2 1.666667    1    3    0
      #3 1.333333    1    2    0
      

      您始终可以通过以下方式转换为您的预期输出,

      do.call(cbind, setNames(lapply(ind, function(i) f1(df[grepl(i, names(df))])), ind))
      #  x.mean1 x.min1 x.max1 x.mad1  y.mean1 y.min1 y.max1 y.mad1
      #1    1.50      1      2 0.7413 1.333333      1      2      0
      #2    1.25      1      2 0.0000 1.666667      1      3      0
      #3    1.50      1      2 0.7413 1.333333      1      2      0
      

      【讨论】:

        【解决方案3】:

        我们也可以为此使用matrixStats 包中的row.. 函数

        library(matrixStats)
        do.call(cbind, lapply(split.default(df1, sub("\\d+", "", names(df1))), function(x) {
           x1 <- as.matrix(x)
          data.frame(mean = rowMeans(x1), min = rowMins(x1), max = rowMaxs(x1), mad = rowMads(x1))}))
        #  x.mean x.min x.max  x.mad   y.mean y.min y.max y.mad
        #1   1.50     1     2 0.7413 1.333333     1     2     0
        #2   1.25     1     2 0.0000 1.666667     1     3     0
        #3   1.50     1     2 0.7413 1.333333     1     2     0
        

        【讨论】:

          猜你喜欢
          • 2014-09-21
          • 1970-01-01
          • 2020-09-23
          • 1970-01-01
          • 2011-08-24
          • 1970-01-01
          • 1970-01-01
          • 2012-10-15
          • 1970-01-01
          相关资源
          最近更新 更多