[英]tryCatch in for loop
我在for循环中运行tryCatch
语句时遇到问题。 我想遍历数据帧( x
)中的每一行,如果在获取k1
列中给定行的sqrt时出错,我希望sqrtd
等于"NULL"
,如果不是,则将其作为sqrt值。
下面是我尝试过的代码,但是每行的新列sqr
为"NULL"
但是只有第二行应该为"NULL"
因为不能使用sqrt("a")
。
library(Jmisc)
library(dplyr)
x <- data.frame(k1 = c(3,"a",3,4,5), k2 = c(1,NA,NA,4,5), data1 = 1:5)
p <- data.frame(NULL)
for (row in 1:nrow(x)){
sqrtd <- tryCatch(sqrt(x$k1[row]),error=function(e) sqrtd = "NULL")
x <- addCol(x,value=c(sqr=sqrtd))
p <- rbind(p,x)
}
print(p)
JMisc的addCol
似乎在整个列的addCol
中添加了一个值(文档混淆地称其为“常数”)。 在您的代码中,您将在第一次迭代后用新值替换现有列。
您的情况下的解决方案是避免for
循环-实际上,data.frames实际上不应在循环内构建。 而是使用R的向量化运算。 如:
sqrt_or_null = function (x) {
tryCatch(sqrt(x), error = function (e) "NULL")
}
p = mutate(x, sqr = lapply(k1, sqrt_or_null))
但是,这将为您留下一个列表列,这是data.frame中的繁琐数据类型。 原因是给定的非列表列只能包含一种类型的值,但是您的函数将根据操作是否成功返回不同的类型: numeric
或character
。
您可以转换结果:
p = mutate(x, sqr = as.character(lapply(k1, sqrt_or_null)))
…但是我建议考虑更好地表示失败值(例如NA
),或者在执行此操作之前避免失败(例如,通过filter
无效行)。
您的代码还有一个问题: k1
的类型是factor
,而不是numeric
。 因此,它将为每个值失败。 您将需要首先将因子值转换为数值,这需要两个步骤:转换为字符串,然后转换为数值:
p = x %>%
mutate(k1num = as.numeric(as.character(k1))) %>%
mutate(sqr = ifelse(is.na(k1num), "NULL", sqrt(k1num)))
每个向量只能是一种类型(例如,数字,逻辑,字符)。 如果尝试在向量分配中包括多个类型,则向量将被强制转换为可以处理输入的最广泛的类型。 如果运行x$k1
,则应注意,结果向量是字符串的字符向量(即"3" "a" "3" "4" "5"
)。 这是因为"a"
是一个字符串,因此整个向量x$k1
被强制转换为字符。 使用此向量中任何元素的平方根都会产生错误,因此sqrtd
始终被分配为"NULL"
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.