Home > Blockchain >  Why logical operations in dataframe iteration doesn't return the right values?
Why logical operations in dataframe iteration doesn't return the right values?

Time:01-15

I'm trying to perform a logic test on two dataframes. If zero is included in the delimited interval between dataframe elements, the label 'Not Significant' must be included, otherwise, if zero is not included, the label 'Significant' must be included.

The code below works fine, except for the case where a[i,] and b[n,] are negative, where it should include the label 'Significant', it returns 'Not Significant' (line 4). How to solve the problem?

CODE:

a<-c(-1,1,-1,-2,1,0,0,-1)
b<-c(1,1,1,-1,1,1,0,0)
a<-as.data.frame(a)
b<-as.data.frame(b)

ab<-matrix(data=NA)

for (i in 1:nrow(a))
    {
      for (n in 1:nrow(b))
      {
        if (a[i,] <= 0 && b[n,] >= 0) {ab[i]<-c('Not Significant')}
        else {ab[i] <-c('Significant')}
      }
        
    }
c<-cbind(a,b,ab)
c

OUTPUT:

a b ab
-1 1 Not Significant
1 1 Significant
-1 1 Not Significant
-2 -1 Not Significant (Should be Significant)
1 1 Significant
0 1 Not Significant
0 0 Not Significant
-1 0 NotSignificant

CodePudding user response:

There is no need to use a nested loop if we want to compare corresponding elements of a and b columns (as they have the same number of rows). Also, a loop is not needed as these are vectorized operations

ab <- ifelse(a$a <=0 & b$b >= 0, "Not Significant", "Significant")
data.frame(a, b, ab)

-output

   a  b              ab
1 -1  1 Not Significant
2  1  1     Significant
3 -1  1 Not Significant
4 -2 -1     Significant
5  1  1     Significant
6  0  1 Not Significant
7  0  0 Not Significant
8 -1  0 Not Significant

In the OP's nested loop

 if (a[i,] <= 0 && b[n,] >= 0) {ab[i]<-c('Not Significant')

the ab[i] gets overrided each time it loops over the b[n,] for the same value of a[i,] and thus it returns the output of the last assignment

Use a print statement to that it becomes more clear

for (i in 1:nrow(a))
    {
      for (n in 1:nrow(b))
      {
        if (a[i,] <= 0 && b[n,] >= 0) {
           
           ab[i]<-c('Not Significant')
           print(paste("a[i,], b[n,]", "i=", i, "n=", n, a[i,], b[n,], "ab[i]", ab[i]))
           
           
           }
        else {ab[i] <-c('Significant')}
      }
        
    }

-print output for 4th row in 'a'

...
[1] "a[i,], b[n,] i= 4 n= 1 -2 1 ab[i] Not Significant"
[1] "a[i,], b[n,] i= 4 n= 2 -2 1 ab[i] Not Significant"
[1] "a[i,], b[n,] i= 4 n= 3 -2 1 ab[i] Not Significant"
[1] "a[i,], b[n,] i= 4 n= 5 -2 1 ab[i] Not Significant"
[1] "a[i,], b[n,] i= 4 n= 6 -2 1 ab[i] Not Significant"
[1] "a[i,], b[n,] i= 4 n= 7 -2 0 ab[i] Not Significant"
...

Here, the 4th element for n is not printed as it is in the else loop and thus even it though it is Significant, in the next iteration i.e. 5, it becomes overrided with "Not Significant"

  • Related