在R中将数据集中的-inf、NaN和NA值替换为零

22

我正在尝试在R中运行一些交易策略。我已经下载了一些股票价格并计算了回报率。新的回报率数据集中有许多-inf、NaN和NA值。我正在复制数据集的一行(log_ret)。它是一个zoo数据集。

library(zoo)
log_ret <- structure(
  c(0.234,-0.012,-Inf,NaN,0.454,Inf), .Dim = c(1L, 6L), 
  .Dimnames = list(NULL, c("x", "y", "z", "s", "p", "t")),
  index = structure(12784, class = "Date"),
  class = "zoo"
)

               x      y    z   s     p   t
2005-01-01 0.234 -0.012 -Inf NaN 0.454 Inf

我该如何用0替换这些不必要的值?

4
is.finite函数用于检查数值是否为有限(finite)的,如果是,则返回TRUE,否则返回FALSE。 - user227710
5个回答

28

InfNANaN可通过!is.finite匹配,例如:

a <- c(1, Inf, NA, NaN)
a[!is.finite(a)] <- 0
# a is now [1, 0, 0, 0]

我对操作 zoo 对象不是很了解,但针对上述示例:

log_ret[1, !is.finite(log_ret)] <- 0

工作。在您的实际数据中,您将不得不循环遍历所有行。可能会有一种zoo特定的方法来做到这一点。

编辑: zoo-specific方法是log_ret[which(!is.finite(log_ret))] <- 0


我以前也尝试过这样做。但出于某种原因,数据集中的任何值都没有改变。 - user2641784
请确保不要混淆 is.finite()is.infinite() - Sergey Skripko

26
根据?zoo的说明:
当用逻辑值作为数据的zoo对象进行下标操作时,其结果未定义。
因此,你需要在下标操作中使用which函数进行包装:
log_ret[which(!is.finite(log_ret))] <- 0
log_ret
               x      y z s     p t
2005-01-01 0.234 -0.012 0 0 0.454 0

17

另一种方法是(其中df为您的数据框):

is.na(df)<-sapply(df, is.infinite)
df[is.na(df)]<-0

我不知道这个方法是否适用于动物园对象,但它避开了is.infinite()仅适用于向量的问题。


1
问题中的 log_ret 不是一个数据框。如果 df 是 log_ret,则此代码会出错。 - G. Grothendieck
@Grubbmeister 第一行代码是否将所有无限值设置为NA,然后第二行代码将所有NA替换为0?如果是的话,第一步是创建一个逻辑向量is.na(df),并将其存储在R中吗? - Din

7

使用dplyr中的mutate_all:

library(dplyr)
fortify.zoo(log_ret) %>% mutate_all(function(x) ifelse(is.infinite(x), 0, x))  

那段代码出现了错误:Error in UseMethod("tbl_vars") : no applicable method for 'tbl_vars' applied to an object of class "zoo" - G. Grothendieck
那个错误已经不再出现了,但它提供了一个数据框而需要的是一个zoo对象。 - G. Grothendieck

5

由于使用 across 已经取代了 mutate_all 的生命周期:

library(dplyr)
fortify.zoo(log_ret) %>% mutate(across(.cols = everything(), ~ ifelse(is.infinite(.x), 0, .x)))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接