【问题标题】:Cannot fill my R for loop无法填充我的 R for 循环
【发布时间】:2017-11-24 19:07:12
【问题描述】:

所以我正在使用如下矩阵处理 R:

diff_0
             SubPop0-1,   SubPop1-1,   SubPop2-1,    SubPop3-1,  SubPop4-1,
SubPop0-1,           NA           NA           NA            NA          NA
SubPop1-1,  0.003403100           NA           NA            NA          NA
SubPop2-1,  0.005481177 -0.002070277           NA            NA          NA
SubPop3-1,  0.002216444  0.005946314  0.001770977            NA          NA
SubPop4-1,  0.010344845  0.007151529  0.004237316 -0.0021275130          NA

...但更大;-)。

这是每个 SubPop 之间从 0 到 4 的成对遗传差异矩阵。我想获得每个 subPop 的平均差异值。

例如,对于 SubPop-0,平均值仅对应于第 1 列中 4 个值的平均值。但是对于 SubPop-2,这将是第 3 行中的 2 个值和第 2 行中的值的平均值第 3 列,因为这是一个半矩阵。

考虑到这一点,我想编写一个 for 循环来计算每个 SubPop 的每个平均值。我尝试了以下方法:

Mean <- for (r in 1:nrow(diff_0)) {
    mean(apply(cbind(diff_0[r,], diff_0[,r]), 1, sum, na.rm=T))
 }

首先,这隔离了索引 [r] 的每一行和每一列,其值引用相同的 SubPop r。 “sum”可以收集这些值并消除“NA”。最后我得到了我的 SubPop r 的平均值。我希望我的 for 循环能给我每个索引 r 的值,这将是一个 SubPop。

然而,尽管我的mean(apply(cbind(diff_0[r,], diff_0[,r]), 1, sum, na.rm=T)),如果单独运行一个介于 1 和 5 之间的固定 r 值,确实给了我想要的;那么'for循环'本身只返回一个空向量。

for (r in 1:nrow(diff_0)) { print(diff_0[r,1]) } 之类的东西也可以,所以我不明白发生了什么。

这是一个微不足道的问题,但我在互联网上找不到答案!虽然我知道我可能错过了明显的:-)...

非常感谢, 干杯!

【问题讨论】:

    标签: r for-loop matrix apply


    【解决方案1】:

    好的,根据您想要做的事情(如果我理解正确的话),有几种方法可以做到这一点。 我现在想到的就是把你的下三角矩阵变成一个“整个矩阵”(即用下三角的转置填充上三角),然后按行或按列表示 我的 R 现在正在其他东西上运行,所以我无法检查我的代码,但这应该可以工作

    diff = diff_0
    diff[upper.tri(diff)] = t(diff_0[lower.tri(diff)]) #This step might need some work
    

    正如我所说,我的 R 现在正在运行,所以我无法检查最后一行的正确性 - 我可能会对那里的一些转置感到困惑,所以我很感激任何关于它是否真的有效的反馈。
    然后,您可以将对角线值设置为 0,或者将 na.rm = TRUE 添加到均值语句中

    mean_diffs = apply(diff,2,FUN = function(x)mean(x, na.rm = TRUE))
    

    应该可以的

    另外:是的,您的代码不起作用,因为赋值不在 for 循环中。这应该有效:

    means = rep(NA, nrow(diff_0)
    for (r in 1:length(means)){
        means[r] = mean(apply(cbind(diff_0[r,], diff_0[,r]), 1, sum, na.rm=T))
    

    但一般来说 for 循环并不是你想要在 R 中做的事情

    【讨论】:

    • 非常感谢:-) 我不知道upper/lower.tri,这确实很有用! diff_0[lower.tri(diff)] 返回一个数字向量,所以转置与实际的半矩阵不完全匹配,但我只需要在这上面多花点时间!还要感谢您对我的 for 循环的反馈!没错,最好尽可能多地分解,知道我知道这个upper.tri函数我可能会尝试用另一种方式让它工作!
    • (顺便说一下,您更正的循环代码确实可以正常工作,再次感谢!!)
    • @Chrys 是的,它应该返回一个数字向量。如果然后将此向量分配给具有正确维度的矩阵(即上三角矩阵),它将按列填充此矩阵。如果我的回答有帮助,请随时将其标记为正确答案(我的答案旁边的绿色勾号)
    • 这是对的,唯一的问题是由于上面的矩阵是逐列填充的,我们失去了矩阵的对称性。肯定有一种方法可以逐行填充它!不幸的是,今晚我将无法继续寻找,但这无论如何真的很有帮助,一旦我找到一种方法来改变填充上部矩阵的方式,我就会马上回来(除非有人在我之前找到,这很有可能;-))再次感谢大家!
    • ... 好吧,这很容易!正好相反:diff &lt;- t(diff_0) diff[lower.tri(diff)] &lt;- diff_0[lower.tri(diff_0)] 以便填充下部矩阵而不是上部矩阵。
    【解决方案2】:

    这可能是一个解决方案...

    for(i in 1:nrow(diff_0)) {
    
        k<-mean(cbind(as.numeric(diff_0[,i]),as.numeric(diff_0[i,])),na.rm=T)
        if(i==1) {
    
        data_mean <- k
        }else{
        data_mean <- rbind(data_mean,k)
        }
    }
    
    colnames(data_mean) <-  "mean"
    rownames(data_mean) <- c("SubPop0","SubPop1","SubPop2","SubPop3","SubPop4")
    
    data_mean
    
                   mean
    SubPop0 0.005361391
    SubPop1 0.003607666
    SubPop2 0.002354798
    SubPop3 0.001951555
    SubPop4 0.004901544
    

    【讨论】:

    • 非常感谢梅丁!这是另一种有趣的方式!
    猜你喜欢
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-29
    • 2021-09-29
    • 1970-01-01
    相关资源
    最近更新 更多