清除Rdataframe中的“Inf”值

在R中,我有一个操作,当我转换dataframe时创build一些Inf值。

我想将这些Inf值转换成NA值。 我所拥有的代码对于大数据来说是很慢的,有没有更快的方法呢?

假设我有以下数据框:

 dat <- data.frame(a=c(1, Inf), b=c(Inf, 3), d=c("a","b")) 

下面的例子是在一个案例中的作品:

  dat[,1][is.infinite(dat[,1])] = NA 

所以我把它推广到下面的循环

 cf_DFinf2NA <- function(x) { for (i in 1:ncol(x)){ x[,i][is.infinite(x[,i])] = NA } return(x) } 

但我不认为这是真的使用R的力量。

选项1

使用data.frame是列的列表,然后使用do.call重新创builddata.frame

 do.call(data.frame,lapply(DT, function(x) replace(x, is.infinite(x),NA))) 

选项2 – data.table

你可以使用data.tableset 。 这避免了一些内部复制。

 DT <- data.table(dat) invisible(lapply(names(DT),function(.name) set(DT, which(is.infinite(DT[[.name]])), j = .name,value =NA))) 

或者使用列号(如果有很多列,可能会更快):

 for (j in 1:ncol(DT)) set(DT, which(is.infinite(DT[[j]])), j, NA) 

计时

 # some `big(ish)` data dat <- data.frame(a = rep(c(1,Inf), 1e6), b = rep(c(Inf,2), 1e6), c = rep(c('a','b'),1e6),d = rep(c(1,Inf), 1e6), e = rep(c(Inf,2), 1e6)) # create data.table library(data.table) DT <- data.table(dat) # replace (@mnel) system.time(na_dat <- do.call(data.frame,lapply(dat, function(x) replace(x, is.infinite(x),NA)))) ## user system elapsed # 0.52 0.01 0.53 # is.na (@dwin) system.time(is.na(dat) <- sapply(dat, is.infinite)) # user system elapsed # 32.96 0.07 33.12 # modified is.na system.time(is.na(dat) <- do.call(cbind,lapply(dat, is.infinite))) # user system elapsed # 1.22 0.38 1.60 # data.table (@mnel) system.time(invisible(lapply(names(DT),function(.name) set(DT, which(is.infinite(DT[[.name]])), j = .name,value =NA)))) # user system elapsed # 0.29 0.02 0.31 

data.table是最快的。 使用sapply会显着降低速度。

使用sapplyis.na<-

 > dat <- data.frame(a=c(1, Inf), b=c(Inf, 3), d=c("a","b")) > is.na(dat) <- sapply(dat, is.infinite) > dat abd 1 1 NA a 2 NA 3 b 

或者你可以使用(给@mnel,这是编辑),

 > is.na(dat) <- do.call(cbind,lapply(dat, is.infinite)) 

这是显着更快。

[<-mapplysapply快一点。

 > dat[mapply(is.infinite, dat)] <- NA 

有了mnel的数据,时间是

 > system.time(dat[mapply(is.infinite, dat)] <- NA) # user system elapsed # 15.281 0.000 13.750