我正在尝试生成一个仅由数字和"(空格(组成的表。我需要用科学记数法来格式化这些数字。问题是,如果我把这个矩阵做成数字类型,那么我就不能使用",因为它不是一个数字,但我需要它是一个空格。如果我制作这个字符类型的矩阵,那么天平库中的"科学"函数无法识别数字,因为它们是数字类型。如果我试图在遍历矩阵中每个元素的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] == "" } }
但请不要用它。如果你用了,不要说我告诉过你用这种方式替换,我会失去我仅有的一点可信度:-(