我有一个列表,我想用R数值'Infinity'
替换字符串Inf
。我尝试了各种方法,但R不断将值Inf
强制转换为字符串'Inf'
。以下是我尝试过的方法:
# Doesn't work
l1 <- list('Infinity')
l1[[1]][l1[[1]] == 'Infinity'] <- Inf
l1
class(l1[[1]])
# Doesn't work
l2 <- list('Infinity')
special.values <- match(l2[[1]], c("Infinity", "-Infinity", "NaN"))
indices <- which(!is.na(special.values))
l2[[1]][indices] <- c(Inf, -Inf, NaN)[na.omit(special.values)]
l2
class(l2[[1]])
不幸的是,我有额外的限制,我不能在整个列表上进行替换,因为列表中的某些元素可能包含'Infinity'
的合法字符串
# This works, but would incorrectly replace data in my use case
l3 <- list('Infinity')
l3 <- replace(l3, l3 == 'Infinity', Inf)
l3
class(l3[[1]])
关于如何使这项工作的任何想法。这是一个更完整的例子,说明我实际编写的代码是什么样的。
l4 <- list(1.0, 'Infinity', 'Infinity')
l4.types <- c('numeric', 'numeric', 'character')
for (i in which(l4.types %in% 'numeric')) {
# insert code here
}
all.equal(l4, list(1.0, Inf, 'Infinity')) # TRUE
答案 0 :(得分:0)
我相信您的代码不起作用,因为当您替换字符向量的元素时,替换将被强制转换为字符。
这在一般情况下是有道理的:
x = c("a", "b", "c")
x[2] = 1
x
# [1] "a" "1" "c"
矢量必须是一种类型,所以上面是唯一的方法。 没有意义进行特殊处理以检查向量是否长度为1,因此我们希望它以完全相同的方式工作,它确实:
# this is consistent:
y1 = "infinity"
y1[1] = Inf
y1
# [1] "Inf"
如果要更改向量的类,则必须替换整个向量或明确强制它:
## replace whole vector (not just an element)
y2 = "infinity"
y2 = Inf
y2
# [1] Inf
## coerce
y3 = "infinity"
y3[1] = Inf
y3 = as.numeric(y3)
y3
# [1] Inf
由于上述两种方法都可以与较长的矢量一致地工作。
由于此处突出显示的代码中的单个括号替换为l1[[1]] [ l1[[1]] == 'Infinity' ] <- Inf
,因此它属于上面的x
和y1
示例。解决方案是相同的,要么替换整个向量,要么明确强制转换为数字。下面我采取“替换整个矢量”的方法。
l4 <- list(1.0, 'Infinity', 'Infinity')
l4.types <- c('numeric', 'numeric', 'character')
for (i in which(l4.types %in% 'numeric')) {
if(l4[[i]] == 'Infinity') l4[[i]] = Inf
}
all.equal(l4, list(1.0, Inf, 'Infinity'))
# [1] TRUE