2017-02-10 119 views
0

主要用于stdevs时有一些麻烦,并且可能还有最佳方法解决方案。计算列平均值和标准偏差组

dat <- data.frame(matrix(rnorm(16*100), ncol=100)) # data 

在这个例子中,我有100列的数据集,我需要得到各行的手段和stdevs在25个样品

组我第一次发现,将做单独

代码
as.data.frame(rowMeans(dat[,1:25]))  # mean of columns 1:25 
as.data.frame(apply(dat[,1:25],1,mean)) # mean of columns 1:25 
as.data.frame(apply(dat[,1:25],1,sd)) # sd of columns 1:25 

起初我用rowMeans并通过下面的循环做这项工作:

dat.means <- list() # create empty list for means 
# mean of every 25 cols 
count <- 1 
for(i in seq(1,length(dat),25)){ 
    dat.means[[count]] <- cbind(rowMeans(as.data.frame(dat[,i:i+24]))) 
    count=count+1 
} 

在这一点上,我找不到相当于rowMeans来计算标准偏差,所以回溯到尝试使用apply。然而,我如何以这种方式使用它的知识却非常缺乏,而且在这一点上我只得到了错误。

for(i in seq(1,length(dat),25)){ 
    dat.means[[count]] <- cbind(apply(dat[,i:i+24],1,mean)) 
    count=count+1 
} 

#Error in apply(dat[, i:i + 24], 1, mean) : 
# dim(X) must have a positive length 

我已经尝试了上述循环的一些其他迭代,但我仍然得到张贴错误。

我也有一种感觉,循环可能不是最好的方法,但是我很茫然。感谢任何帮助。

针对疑似重复问题here 计算SD和与NA值的数据帧的意思是不是这里的问题,问题是如何在一个更大的数据帧在列组有效应用的功能

+1

[手段并且与NA值的数据帧的SD为列(的可能的复制http://stackoverflow.com/questions/20794284/means-and-sd-for-columns -in-a-dataframe-with-na-values) –

回答

0

在基础R可以tapply你行的相同长度的载体使用。

t(apply(dat, 1, function(row){ 
    tapply(row, INDEX=rep(1:4,c(25,25,25,25)), mean) # or sd 
}) 
) 

因此,我们在每行的数据集上运行apply。这被传递到tapply,其中该行中的每个元素的索引被分类为数字1,2,3,e.t.c(在这种情况下与row的长度相同)。并根据需要应用该功能。

输出:

    1   2   3   4 
[1,] -0.121142260 0.09109255 0.14969065 -0.008491494 
[2,] 0.100938120 0.05852706 0.01694019 0.142837311 
[3,] -0.270040421 -0.13509216 -0.02526398 0.176398683 
[4,] -0.098860947 -0.02428447 0.34782123 -0.113218821 
[5,] 0.058705197 0.25760489 0.30359424 0.457067044 
[6,] -0.004329987 0.16322551 -0.20793649 -0.100291690 
[7,] 0.146482094 0.08483679 0.16754837 -0.027107295 
[8,] 0.013796914 -0.09084366 0.23347784 -0.194043232 
[9,] -0.292440563 0.03362355 0.03668636 -0.113120322 
[10,] -0.083525957 -0.04704885 0.21239136 0.378796710 
[11,] 0.355684510 -0.34531764 -0.17021181 -0.293445102 
[12,] 0.165324616 -0.32272002 -0.28986401 -0.135609262 
[13,] 0.134330325 -0.04966847 0.22928705 0.012515783 
[14,] -0.117367280 0.14220143 0.03655234 -0.175041681 
[15,] 0.313223877 0.29656269 -0.14042955 -0.173458094 
[16,] 0.062781966 0.09551260 -0.05704605 0.048142911 
+0

这看起来不错。任何想法如何自动化索引?例如。变量为'replicates = 25;独特= 4'。我只是尝试了像tapply(row,INDEX = rep(1:uniques,rep(replicates,uniques),mean))''没有成功。 – user3564760

+0

嗯好吧,我想我一定搞砸了上面的代码。我再次在我的评论中尝试了代码,它工作。谢谢! – user3564760

4

使用data.table包:

# load 'data.table' 
library(data.table) 

# melt into long format and add 'row.id' variable with number of each row 
dat2 <- melt(setDT(dat)[, row.id := .I], id = 'row.id') 

# create a grouping variable for each block of 25 values 
dat2[, grp := rep(1:4, each = 25), by = row.id] 

# summarise 
dat2[, .(mn = mean(value), std = sd(value)), by = .(row.id,grp)] 

这给:

row.id grp   mn  std 
1:  1 1 -0.30388554 1.0307631 
2:  2 1 0.04381967 0.7939788 
3:  3 1 0.03106169 0.8581719 
4:  4 1 -0.15215035 0.8200987 

.... 

15:  15 1 -0.23641918 0.7024393 
16:  16 1 0.09745967 1.0253811 
17:  1 2 -0.16414997 0.8695713 
18:  2 2 -0.06763887 1.0294245 

.... 

31:  15 2 0.06034238 0.7756055 
32:  16 2 0.16387033 0.9285894 
33:  1 3 0.32860736 1.0802055 
34:  2 3 0.51183174 0.9562819 

.... 

47:  15 3 0.16075275 1.0335789 
48:  16 3 -0.43298467 1.1010562 
49:  1 4 0.24918962 0.9580600 
50:  2 4 -0.13005426 1.1693455 

.... 

62:  14 4 0.02436604 0.7341284 
63:  15 4 -0.19614383 0.7039496 
64:  16 4 0.01182338 0.8465747 

运作方式:

  • 随着setDT(dat)数据帧被转换成data.table(这是一个data.frame的增强形式)
  • [, row.id := .I]添加变量与ROWNUMBER然后
  • melt用于将数据转换为以rownumber作为标识符的长格式。
  • 接下来,对于每个row.id,创建分组变量,其中rep(1:4, each = 25)创建25 1的向量,然后创建25 2等。因此,例如,row.id == 1(其对应于原始dat-数据帧的前25列)的前25个值获得组编号1,第二25个值获得组编号2,依此类推。
  • 接下来你总结dat2[, .(mn = mean(value), std = sd(value)), by = .(row.id,grp)]你使用row.idgrp作为分组变量。

结果是每行的每组列的平均值和标准偏差。


另一种选择是使用的dcastmelt和可能性的组合在dcast指定多个集合函数:

dcast(melt(setDT(dat)[, row.id := .I], id = 'row.id')[, grp := rep(1:4, each = 25), by = row.id], 
     row.id ~ grp, fun.aggregate = list(mean, sd)) 

其给出:

row.id value_mean_1 value_mean_2 value_mean_3 value_mean_4 value_sd_1 value_sd_2 value_sd_3 value_sd_4 
1:  1 -0.30388554 -0.16414997 0.32860736 0.24918962 1.0307631 0.8695713 1.0802055 0.9580600 
2:  2 0.04381967 -0.06763887 0.51183174 -0.13005426 0.7939788 1.0294245 0.9562819 1.1693455 
3:  3 0.03106169 -0.07250312 0.21619928 0.13092043 0.8581719 1.1439506 0.9441762 1.0006230 
4:  4 -0.15215035 -0.08417522 -0.27278714 -0.04190002 0.8200987 0.9008114 1.0394255 1.2063465 
5:  5 0.21871123 0.08029101 -0.04965507 -0.15279897 0.9593703 0.8409534 0.8878550 1.0157824 
6:  6 0.22335221 0.27142844 0.14032413 0.09975956 1.1154142 1.0896226 0.8587636 1.1147968 
7:  7 0.16725794 -0.03462013 0.14675249 -0.15678569 0.9991910 0.9236954 1.1258560 1.0250408 
8:  8 -0.12872236 0.03884649 -0.48565736 -0.30525278 1.0118579 1.0266040 1.1284902 0.9048042 
9:  9 0.25986114 0.25181718 0.07673463 -0.11521187 1.0509685 0.8352278 1.0952720 1.0706587 
10:  10 -0.32670802 -0.04590547 0.22610217 0.09406650 1.0674699 0.8378048 0.8128130 0.9126611 
11:  11 -0.16219092 -0.24172025 -0.14231462 0.03671087 1.1617784 1.0522955 0.8899262 0.8982543 
12:  12 0.21109682 0.19735885 -0.039-0.19283362 0.9064956 0.9530479 1.0422911 0.8323033 
13:  13 0.11926882 0.29611127 -0.37648849 -0.08673776 1.0739078 0.7220276 0.9455307 0.9623676 
14:  14 0.26478861 0.16054927 -0.03315950 0.02436604 1.0555501 1.0713119 0.9112082 0.7341284 
15:  15 -0.23641918 0.06034238 0.16075275 -0.19614383 0.7024393 0.7756055 1.0335789 0.7039496 
16:  16 0.09745967 0.16387033 -0.43298467 0.01182338 1.0253811 0.9285894 1.1010562 0.8465747 

随着dplyr/tidyr

library(dplyr) 
library(tidyr) 
dat %>% 
    mutate(id = row_number()) %>% 
    gather(k, v, 1:100) %>% 
    group_by(id) %>% 
    mutate(grp = rep(1:4, each = 25)) %>% 
    group_by(id, grp) %>% 
    summarise(mn = mean(v), std = sd(v)) 

或者与基础R:

dat2 <- reshape(data = dat, ids = rownames(dat), direction = 'long', varying = list(names(dat)), times = names(dat)) 
dat2 <- transform(dat2, grp = ave(id, id, FUN = function(i) rep(1:4, each = 25))) 
aggregate(X1 ~ id + grp, dat2, FUN = function(x) c(std = sd(x), mn = mean(x))) 
+0

我不知道这是否正确,我试图让每个25列的平均值/ sd,这应该导致总共4列。尽管如此,我仍然在浏览代码。 – user3564760

+0

@ user3564760我已经用解释更新了答案 – Jaap

相关问题