多个类似命名列的统计信息

时间:2017-06-17 17:12:01

标签: r statistics dplyr

我有一个包含多个列的庞大数据集,例如x1x2x3 ...... x25y1,{{1 }},y2 ...... y3y50z1 ....... z2等看起来像这样:

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 minmax(中位绝对偏差)和mad

mean

和其他行和其他统计数据类似。我如何在R中执行此操作,最好是在dplyr中?

3 个答案:

答案 0 :(得分:6)

通常,您可以使用summarise的范围变体,例如summarise_allfuns辅助函数可以接受任意数量的汇总函数。在您的情况下,您应首先重塑为长形式,以便生成数据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

如果您愿意,可以将其重新整理回来,但除了演示目的之外,我可以提出反对意见。

答案 1 :(得分: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

答案 2 :(得分:1)

我们还可以使用row..包中的matrixStats函数来实现此目的

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