需要有条件地将函数应用于字符矩阵中的每个元素



我正在尝试生成一个仅由数字和"(空格(组成的表。我需要用科学记数法来格式化这些数字。问题是,如果我把这个矩阵做成数字类型,那么我就不能使用",因为它不是一个数字,但我需要它是一个空格。如果我制作这个字符类型的矩阵,那么天平库中的"科学"函数无法识别数字,因为它们是数字类型。如果我试图在遍历矩阵中每个元素的for循环中编写If语句,那么该条件只应用于生成以下错误的第一个元素:

if(moduleTraitPvalueSig!="(中的错误{:缺少需要TRUE/FALSE的值此外:警告消息:In if(moduleTraitPvalueSig!="({:条件的长度>1,并且只有第一个元素将被使用

我使用的是一个名为moduleTraitPvalueSig的矩阵,产生上述错误的代码就是这样的

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

if(moduleTraitPvalueSig!="(中的错误{:

缺少值,其中TRUE/FALSE需要

此外:警告信息:

In if(moduleTraitPvalueSig!="({:

条件的长度>1,并且只有第一个元素将被使用

不要混淆数字使用和计算与渲染。在准备好打印/渲染之前,您不应该担心科学符号和空格。

一些样本数据:

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

您不需要循环,只需一次转换所有循环即可。

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"

不幸的是,scale::scientific并不关心NA(奇怪!(,但这对我们来说并没有太大改变,我们可以这样重新分配:

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"

关于代码/错误的其他注意事项:

  • the condition has length > 1是因为if (condition) { ... }需要长度恰好为1的条件。由于您正在比较整个对象,因此它返回的长度(TRUE/FALSE/NA(等于对象的总尺寸;也就是说,如果你的矩阵是3x5,那么你的if语句被赋予了15个逻辑。它只需要一个,其他的都是错误。矢量化if/else是用ifelse(cond, true_expr, false_expr)完成的,但那是另一回事(这里根本不需要它(。SO上有无数的问题引用了这个精确的错误消息,我建议你可以在上面做更多的搜索以获取更多信息。

  • 当逻辑返回的长度为0而不是1(预期(或大于1(您收到的另一个错误(时,missing value where TRUE/FALSE needed通常是相关的。这个错误在SO上也很常见,研究会给你很多例子和方法来调查/修复它

  • 如果您要按元素进行矩阵比较(考虑到您想要做的事情,在R中效率非常低(,那么至少可以使用for循环值。使用我上面生成的m矩阵,这将把代码变成类似于:

    # 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] == ""
    }
    }
    

    但请不要用它。如果你用了,不要说我告诉过你用这种方式替换,我会失去我仅有的一点可信度:-(

最新更新