简体   繁体   中英

Need to conditionally apply function to every element in a character matrix

I'm trying to generate a table that only consists of numbers and "" (blank spaces). I need the numbers to be formatted using scientific notation. The issue is, is that if I make this matrix of a numeric type, then I can't use "" since it is not a number, but I need it to be a blank space. If I make this matrix of character type, then the 'scientific' function from the scales library does not recognize the numbers since they are numeric type. If I try to write an if statement within a for loop that iterates through every element in my matrix, then the condition is only applied to the first element generating the following error below:

Error in if (moduleTraitPvalueSig != "") { : missing value where TRUE/FALSE needed In addition: Warning message: In if (moduleTraitPvalueSig != "") { : the condition has length > 1 and only the first element will be used

I am using a matrix called moduleTraitPvalueSig, and the code that geneates the error above is as such

library(scales)
moduleTraitPvalueSig <- moduleTraitPvalue;
moduleTraitPvalueSig[moduleTraitPvalueSig>=0.05]<- ""
for(row in 1:nrow(moduleTraitPvalueSig)) {
  for(col in 1:ncol(moduleTraitPvalueSig)) {
    if(moduleTraitPvalueSig!="")
    {scientific(moduleTraitPvalueSig)}
  }
}

Error in if (moduleTraitPvalueSig != "") { :

missing value where TRUE/FALSE needed

In addition: Warning message:

In if (moduleTraitPvalueSig != "") { :

the condition has length > 1 and only the first element will be used

Don't confuse number use and calculations with rendering. You shouldn't be worrying about scientific notation and spaces until you are ready to print/render.

Some sample data:

m <- matrix(pi, nr=3, nc=3)
m[1,2] <- m[2,3] <- NA
m
#          [,1]     [,2]     [,3]
# [1,] 3.141593       NA 3.141593
# [2,] 3.141593 3.141593       NA
# [3,] 3.141593 3.141593 3.141593

You don't need a loop, just convert all at once.

m[] <- scales::scientific(m)
m
#      [,1]       [,2]       [,3]      
# [1,] "3.14e+00" "NA"       "3.14e+00"
# [2,] "3.14e+00" "3.14e+00" "NA"      
# [3,] "3.14e+00" "3.14e+00" "3.14e+00"

Unfortunately, scale::scientific cares not about NA (odd!), but that doesn't change things much for us, we can re-assign this way:

m[ m == "NA" ] <- ""
m
#      [,1]       [,2]       [,3]      
# [1,] "3.14e+00" ""         "3.14e+00"
# [2,] "3.14e+00" "3.14e+00" ""        
# [3,] "3.14e+00" "3.14e+00" "3.14e+00"

Other notes about your code/errors:

  • the condition has length > 1 is because if (condition) { ... } requires a condition of length precisely 1. Since you are comparing your whole object, it is returning a length (of TRUE / FALSE / NA ) equal in length to the total dimensions of your object; that is, if your matrix is 3x5, then your if statement is being given 15 logicals. It takes only one, anything else is an error. Vectorizing if/else is done with ifelse(cond, true_expr, false_expr) , but that's a different story (and you do not need it at all here). There are countless questions on SO that reference this precise error message, I suggest you can do a bit more searching on it for more info.

  • missing value where TRUE/FALSE needed is often related, given when the length of logical returns is 0 instead of 1 (expected) or more than 1 (the other error you received). This error as well is very frequent on SO, research will give you plenty of examples and ways to investigate/fix it.

  • if you are going to do the matrix comparisons element-wise (very inefficient in R given what you intend to do), then at least you can use your for loop values. Using the m matrix I generated above, that would turn the code into something like:

     # you could use this in place of `m[ m == "NA" ] <- ""` for (i in seq_len(nrow(m))) { for (j in seq_len(ncol(m))) { if (m[i,j] == "NA") m[i,j] == "" } } 

    but please don't use it. If you do, don't say I told you to do that kind of replacement in this way, I'll lose what little credibility I've got :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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