gpt4 book ai didi

r - R 中的一个如何在矩阵上应用带有 "for"语句的 "if"函数来创建平滑函数

转载 作者:行者123 更新时间:2023-12-04 09:41:07 29 4
gpt4 key购买 nike

所以这是我的问题:

我有一个包含大量数据点的巨大 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
.
.
.

每个实验都可以用直方图表示,但需要通过四个相邻实验的平均值来平滑这些值。因此,例如 matrix[1,3] 中的值 845 将被 mean(matrix[1,1]:matrix[1,5]) 覆盖。出现的问题是在 matrix[1,1] 位置。因为没有左邻居,所以平滑不起作用并引发错误。由于列表示范围从 360° 的圆形维度,因此 coln 处的值实际上表示 col1< 的左邻域.

如果我提取矩阵 (x=matrix[1,]) 的 exp_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 创建了一些玩具数据:

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

最后,您可以使用 zoo 包中的 rollapply 函数来计算运行平均值。请注意,您必须先安装 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。事实确实如此。

关于r - R 中的一个如何在矩阵上应用带有 "for"语句的 "if"函数来创建平滑函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58746099/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com