简体   繁体   English

ifelse与for循环

[英]ifelse with for loop

I would like to traverse through rows of a matrix and perform some operations on data entries based on a condition. 我想遍历矩阵的行并根据条件对数据条目执行一些操作。

Below is my code 下面是我的代码

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)
                }
        }
}

I get a warning message as below in my "if" condition 在“如果”状态下,我收到如下警告消息

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

I know it returns a vector and I should be using ifelse block. 我知道它返回一个向量,我应该使用ifelse块。 How to incorporate for loops inside ifelse block? 如何在ifelse块中合并for循环? It seems to be a basic question, I am new to R. 这似乎是一个基本问题,我是R的新手。

Based on your description, you want to check the number of non NA in matrix by column and then do something dependent on this results (that why you need "if"/"ifelse" statement). 根据您的描述,您希望按列检查矩阵中非NA的数量,然后根据此结果执行某些操作(这就是为什么需要“ if” /“ ifelse”语句的原因)。 So, you can implemented as below, and write inner loops in a specific function. 因此,您可以如下实现,并在特定函数中编写内部循环。

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

Actually, I think you need to re-organize your problem and optimize the code, the "ifelse with for loop" may be totally unnecessary. 实际上,我认为您需要重新组织问题并优化代码,“ if forse循环”可能完全没有必要。

As you are new to R, I assume that some of the terminology is maybe a bit confusing. 当您不熟悉R时,我认为某些术语可能有点令人困惑。 So here is a little explanation regarding the if statement . 因此,这里有一些有关if statement解释。

Lets look at the if condition : 让我们看一下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

This is nothing that if can work with as an if condition has to be boolean (evaluate to TRUE/FALSE). if condition必须为布尔值 (评估为TRUE / FALSE), if不能与之配合使用。 So why the result? 那么为什么要结果呢? Well the result of 好吧

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

is a vector of counts of entries that are not NA ! 不是条目数的向量NA (= number of TRUE's in each column). (=每列中的TRUE数)。 Be carful as this is not the same as 要carful因为这是一样的

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

which returns a vector of sums over all five rows for each column, excluding NA 's. 它返回每列的所有五行之和的向量,不包括NA My guess is that the latter is what you are looking for. 我的猜测是,后者就是您要寻找的。 In any case: be aware of the difference! 无论如何:请注意其中的区别!
By asking which of those sums is greater than 1 you do get a boolean vector 通过询问这些和中的哪个大于1,您确实获得了布尔向量

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

However, using that boolean vector as a criteria for selecting columns, you correctly get a matrix which is obviously not boolean: 但是,使用该布尔向量作为选择列的标准,您正确地获得了一个显然不是布尔值的矩阵:

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

Note: drop = FALSE is unnecessary here as there are no dimensions to be dropped potentially. 注意: drop = FALSE在这里是不必要的,因为没有可能要删除的尺寸。 See ? 看到了吗? [ or ?drop . [?drop You can verify this using identical : 您可以使用identical方法进行验证:

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

Now to the loop. 现在到循环。 You find tons of discussions on avoiding for loops and using the apply family of functions . 您会发现有关避免循环使用apply函数族的大量讨论。 I suspect you have to take some time togo through all that. 我怀疑您必须花一些时间来完成所有这些工作。 Note however, that using apply - contrary to common belief - is not necessarily superior to a for loop in terms of speed, as it is actually just a fancy wrapper around a for loop (check the source code!). 但是请注意,与常识相反,使用apply在速度方面不一定优于for循环,因为它实际上只是for循环周围的精美包装(请查看源代码!)。 It is, however, clearly superior in terms of code clarity as it is compact and clear about what it is doing. 但是,它在代码清晰性方面明显优越,因为它紧凑且清楚其功能。 So do try to use apply functions if possible! 因此,如果可能,请尝试使用apply函数!

In order to rewrite your loop it would be helpful if you could verbally describe what you actually want to do, since I assume that what the loop is doing right now is probably not what you want. 为了重写循环,如果您可以口头描述您实际想要做什么,将很有帮助,因为我认为循环现在正在做的可能不是您想要的。 As which() returns the index/posistion of an element in a vector or matrix what you are basically doing is: which()返回向量或矩阵中元素的索引/位置时,您基本上在做的是:

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

While this is theoretically possible, this usually doesnt make much sense. 尽管从理论上讲这是可能的,但这通常没有多大意义。 So with all my notes at hand: clearly state your problem so we can think of a fix. 因此,请注意我的所有注释:清楚说明您的问题,以便我们考虑解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM