ifelse with for循环

时间:2015-12-08 06:47:20

标签: r matrix

我想遍历矩阵的行,并根据条件对数据条目执行一些操作。

以下是我的代码

m = matrix(c(1,2,NA,NA,5,NA,NA,1,NA,NA,NA,NA,4,5,NA,NA,NA,NA,NA,NA), nrow = 5, ncol = 4)
if (m[,colSums(!is.na(m)) > 1, drop = FALSE]){
        for(i in 1:4){
              a = which(m[i,] != "NA") - mean(which(!is.na(m[i,])))
                for(j in 2:5){
                       b = which(m[j,] != "NA") - mean(which(!is.na(m[j,])))
                       prod(a,b)
                }
        }
}

我收到的警告信息如下所示" if"条件

Warning message:
In if (m[, colSums(!is.na(m)) > 1, drop = FALSE]) { :
  the condition has length > 1 and only the first element will be used

我知道它返回一个向量,我应该使用ifelse块。如何在ifelse块中包含for循环?这似乎是一个基本问题,我是R的新手。

2 个答案:

答案 0 :(得分:0)

根据您的描述,您希望逐列检查非NA的数量,然后根据此结果执行某些操作(这就是您需要的原因"如果" /" ifelse&#34 ;声明)。因此,您可以按照以下方式实现,并在特定函数中编写内部循环。

yourFunc <- function(x, data) {
 # do what your want / your loops on "data"
 # sample, you can check the result in here
 if(x > 1)  1
 else       0
}

m = matrix(c(1,2,NA,NA,5,NA,NA,1,NA,NA,NA,NA,4,5,NA,NA,NA,NA,NA,NA), nrow = 5, ncol = 4)
# use "apply" series function in here
sapply(colSums(!is.na(m)), yourFunc, data=m)
#[1] 1 0 1 0

实际上,我认为你需要重新组织你的问题并优化代码,&#34; ifelse with for循环&#34;可能完全没必要。

答案 1 :(得分:0)

当你是R的新手时,我认为某些术语可能有点过时 混乱。所以这里有关于if statement的一点解释。

让我们看一下if condition

m[,colSums(!is.na(m)) > 1, drop = FALSE]

      [,1] [,2]
[1,]    1   NA
[2,]    2   NA
[3,]   NA    4
[4,]   NA    5
[5,]    5   NA

这不是if可以使用if condition所必需的 布尔(评估为TRUE / FALSE)。那结果呢?

的结果
colSums(!is.na(m))
[1] 3 1 2 0

是条目的计数向量 NA(=每列中的TRUE数)。请小心,因为

相同
colSums(m, na.rm = TRUE)
[1] 8 1 9 0

返回每列所有五行的和的向量,不包括NA。我的猜测是后者是你正在寻找的。在任何情况下:注意区别!
通过询问哪些总和大于1,你会得到一个布尔矢量

colSums(!is.na(m)) > 1
[1]  TRUE FALSE  TRUE FALSE

但是,使用该布尔向量作为选择列的标准,您正确地得到一个显然不是布尔值的矩阵:

m[,colSums(!is.na(m)) > 1]

注意:此处不需要drop = FALSE,因为没有可能会丢弃的维度。请参阅?[?drop。您可以使用identical验证这一点:

identical(m[,colSums(!is.na(m)) > 1, drop = FALSE],
          m[,colSums(!is.na(m)) > 1])

现在进入循环。您可以使用apply系列函数找到关于避免循环的大量讨论。我怀疑你需要花一些时间来解决这些问题。但请注意,使用apply - 与普遍看法相反 - 在速度方面不一定优于for循环,因为它实际上只是围绕for循环的奇特包装(检查源代码!)。然而,它在代码清晰度方面明显优越,因为它紧凑而清晰地表明它正在做什么。所以尽可能尝试使用apply函数!

为了重写你的循环,如果你能口头上的话会很有帮助 描述你实际想做什么,因为我假设循环是什么 现在正在做的可能不是你想要的。当which()返回向量或矩阵中元素的索引/位置时,基本上就是这样 做的是:

indices of the i'th row that are not NA (for a given column) - mean over these indices

虽然这在理论上是可行的,但这通常没有多大意义。所以我手边的所有笔记都清楚地说明你的问题所以我们可以考虑修复。