所以这是我的问题:
我有一个很大的csv文件,其中包含很多数据点。每行代表属于实验的值。
col1 , col2, col3, col4, col5, col6, ..., coln-1, coln
exp_1 190 10000 845 20 100 67 ..., 2 634
exp_2 3 567 87 465 23 867 ..., 987 43
.
.
.
每个实验都可以用直方图表示,但是需要通过四个邻居的平均值对值进行平滑处理。因此,例如处的值845matrix[1,3]
将被覆盖mean(matrix[1,1]:matrix[1,5])
。发生的问题是在位置matrix[1,1]
。因为没有左邻居,所以平滑不起作用,并引发错误。由于这些列代表的圆形尺寸从0°
到360°
的值coln
实际代表的左邻居col1
。
如果我提取exp_1
矩阵(x=matrix[1,]
)的向量并将其作为以下代码的输入参数,则一切运行顺利。
for ( i in 1:length(x)){
if (i < 2) {
x[i] = mean(c(x[i:(i+2)],x[(length(x)-i):(length(x))]))
} else if (i >= 2){
x[i] = mean(x[(i-2):(i+2)])
} else if (i > (length(x)-2)){
x[i] = mean(c(x[(i-2):i],x[1:abs(length(x)-(i+2))]))
}
}
由于我的矩阵有大量的实验,因此我想循环遍历矩阵,而不是单枪匹马抽出每一行并在其上运行脚本。因此,我尝试将脚本写入函数,如下所示:
smoothing_function = function(x){
for ( i in 1:length(x)){
if (i < 2) {
x[i] = mean(c(x[i:(i+2)],x[(length(x)-i):(length(x))]))
} else if (i >= 2){
x[i] = mean(x[(i-2):(i+2)])
} else if (i > (length(x)-2)){
x[i] = mean(c(x[(i-2):i],x[1:abs(length(x)-(i+2))]))
}
}
}
然后我想得到apply(matrix,1,smoothing_function)
什么结果NULL
。我还尝试了整个矩阵的每一列的mapply(smoothing_function,matrix)
结果NULL
。
我认为问题出在length(x)
零件内部,因为输入参数不是向量而是单个元素。因此,该函数无法计算任何邻居的平均值,因为单个元素的长度为1
。
因此,要么我需要为矩阵中的每个实验生成一个向量,要么需要修改我的函数。你们有什么主意吗?
避免循环和if
条件的一种可能性是创建一个新的矩阵,在该矩阵中,将最后两列粘贴在开头,将前两列粘贴在结尾。
这是一个小例子。首先,我使用rpois
以下命令创建一些toydata :
set.seed(1)
my_matrix <- matrix(rpois(20, 10), 2, 10)
colnames(my_matrix) <- paste0("col", 1:10)
my_matrix
col1 col2 col3 col4 col5 col6 col7 col8 col9 col10
[1,] 8 7 14 11 14 8 8 7 11 12
[2,] 10 11 12 9 11 2 10 12 12 10
然后通过在开头和结尾添加列来扩展此矩阵:
my_matrix2 <- cbind(my_matrix[, 9:10], my_matrix, my_matrix[, 1:2])
my_matrix2
col9 col10 col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 col1 col2
[1,] 11 12 8 7 14 11 14 8 8 7 11 12 8 7
[2,] 12 10 10 11 12 9 11 2 10 12 12 10 10 11
最后,您可以使用包中的rollapply
函数zoo
来计算运行均值。请注意,您必须先安装zoo
软件包。
my_matrix_smooth <- t(apply(my_matrix2, 1, function(z) zoo::rollapply(z, width = 5, FUN = mean)))
col1 col2 col3 col4 col5 col6 col7 col8 col9 col10
[1,] 10.4 10.4 10.8 10.8 11.0 9.6 9.6 9.2 9.2 9
[2,] 11.0 10.4 10.6 9.0 8.8 8.8 9.4 9.2 10.8 11
为了检查这是否正确,我们可以(例如)查看col10
第一行。平滑版本应为(7+11+12+8+7) / 5 = 9
。的确如此。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句