要添加替代方案,您还可以使用replace
代替典型blah[index] <- NA
方法.replace
看起来像:
df <- replace(df, df == "NA", NA)
另一个需要考虑的选择是type.convert
.这是R在读取数据时使用的函数,用于自动转换列类型.因此,结果与您当前的方法不同,例如,第二列转换为数字.
df[] <- lapply(df, function(x) type.convert(as.character(x), na.strings = "NA")) df
这是性能比较.样本数据来自@ roland的回答.
以下是要测试的功能:
funop <- function() { df[df == "NA"] <- NA df } funr <- function() { ind <- which(vapply(df, function(x) class(x) %in% c("character", "factor"), FUN.VALUE = TRUE)) as.data.table(df)[, names(df)[ind] := lapply(.SD, function(x) { is.na(x) <- x == "NA" x }), .SDcols = ind][] } funam1 <- function() replace(df, df == "NA", NA) funam2 <- function() { df[] <- lapply(df, function(x) type.convert(as.character(x), na.strings = "NA")) df }
这是基准测试:
library(microbenchmark) microbenchmark(funop(), funr(), funam1(), funam2(), times = 10) # Unit: seconds # expr min lq mean median uq max neval # funop() 3.629832 3.750853 3.909333 3.855636 4.098086 4.248287 10 # funr() 3.074825 3.212499 3.320430 3.279268 3.332304 3.685837 10 # funam1() 3.714561 3.899456 4.238785 4.065496 4.280626 5.512706 10 # funam2() 1.391315 1.455366 1.623267 1.566486 1.606694 2.253258 10
replace
与@ roland的方法相同,这与@ jgozal的方法相同.但是,该type.convert
方法会导致不同的列类型.
all.equal(funop(), setDF(funr())) all.equal(funop(), funam()) str(funop()) # 'data.frame': 10000000 obs. of 3 variables: # $ vect1: Factor w/ 3 levels "BANANA","HELLO",..: 2 2 NA 2 1 1 1 NA 1 1 ... # $ vect2: Factor w/ 3 levels "1","5","NA": NA 2 1 NA 1 NA NA 1 NA 2 ... # $ vect3: Factor w/ 1 level "NA": NA NA NA NA NA NA NA NA NA NA ... str(funam2()) # 'data.frame': 10000000 obs. of 3 variables: # $ vect1: Factor w/ 2 levels "BANANA","HELLO": 2 2 NA 2 1 1 1 NA 1 1 ... # $ vect2: int NA 5 1 NA 1 NA NA 1 NA 5 ... # $ vect3: logi NA NA NA NA NA NA ...