我有一个包含多个列的庞大数据集,例如x1
,x2
,x3
...... x25
,y1
,{{1 }},y2
...... y3
,y50
,z1
....... 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
,min
,max
(中位绝对偏差)和mad
mean
和其他行和其他统计数据类似。我如何在R中执行此操作,最好是在dplyr中?
答案 0 :(得分:6)
通常,您可以使用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
如果您愿意,可以将其重新整理回来,但除了演示目的之外,我可以提出反对意见。
答案 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