R 将NAs更改为';无';,0或99
我有一个包含50列的数据集,我想编写一个函数,为存在NAs的50列中的每一列分配一个零、“无”或99(如我指定的)。我可以为每一列编写一行代码(在我下面的示例中),但我认为一定有一种方法可以通过一个函数来实现这一点,该函数可以减少我需要编写的代码量 下面是一个有四列的示例R 将NAs更改为';无';,0或99,r,function,dataframe,na,R,Function,Dataframe,Na,我有一个包含50列的数据集,我想编写一个函数,为存在NAs的50列中的每一列分配一个零、“无”或99(如我指定的)。我可以为每一列编写一行代码(在我下面的示例中),但我认为一定有一种方法可以通过一个函数来实现这一点,该函数可以减少我需要编写的代码量 下面是一个有四列的示例 set.seed(1) dat <- data.frame(one = rnorm(15), two = sample(LETTERS, 15),
set.seed(1)
dat <- data.frame(one = rnorm(15),
two = sample(LETTERS, 15),
three = rnorm(15),
four = runif(15))
dat <- data.frame(lapply(dat, function(x) { x[sample(15, 5)] <- NA; x }))
head(dat)
str(dat)
dat$two <- as.character(dat$two)
dat[["one"]][is.na(dat[["one"]])] <- 0
dat[["two"]][is.na(dat[["two"]])] <- 'none'
dat[["three"]][is.na(dat[["three"]])] <- 99
dat[["four"]][is.na(dat[["four"]])] <- 0
head(dat)
set.seed(1)
dat您可以尝试(假设第二列是字符
)
dat[is.na(dat)]您可以同时更改多个列:
columns_to_change <- c("one","four")
dat[columns_to_change] <- lapply(dat[columns_to_change], function(x) replace(x, is.na(x), 0))
columns_to_change <- c("two")
dat[columns_to_change] <- lapply(dat[columns_to_change], function(x) replace(x, is.na(x), "none"))
columns_to_change <- c("three")
dat[columns_to_change] <- lapply(dat[columns_to_change], function(x) replace(x, is.na(x), 99))
columns\u to\u change也许您正在寻找如下函数:
naSwitcher <- function(indf, cols, naType) {
if (length(cols) != length(naType)) stop("Something's wrong")
indf[cols] <- lapply(seq_along(indf[cols]), function(x) {
switch(naType[x],
"0" = { indf[cols[x]][is.na(indf[cols[x]])] <- 0; indf[cols[x]] },
"none" = { indf[cols[x]][is.na(indf[cols[x]])] <- "none"; indf[cols[x]] },
"99" = { indf[cols[x]][is.na(indf[cols[x]])] <- 99; indf[cols[x]] },
"NA" = { indf[cols[x]] },
stop("naType must be either '0', 'none', '99', or 'NA'"))
})
indf
}
(但我建议坚持NA
值…为什么我们要让痣参与进来?:-)你为什么要这样做?它最终会降低数据集的可用性。如果您正在寻找更复杂的NA
处理,也许您应该看看“memisc”包。我已经演示了它的NA
选项。在任何情况下,您都需要用文字清楚地描述替换NA
的标准。例如,我不清楚为什么“一”(一个数字)中的NA
s被替换为0,而“三”(也是数字)中的NA
s被替换为99。这将把所有列转换为字符
@Marek,谢谢。你是对的。我没有仔细看。我认为基于lappy()
的方法更合适。@Marek提供的解决方案(不含代码重复)就是我为这个特定问题选择的解决方案。我喜欢这个简短的函数和按列名称引用列的功能。如果需要的话,我也可以只更改一些列。
dat[] <- lapply(dat, function(x) if(!any(grepl("[[:alpha:]]+",x))) as.numeric(x) else x)
dat[is.na(dat)] <- list(0,'none',99,0)[col(dat)][is.na(dat)]
dat[] <- lapply(dat, unlist)
str(dat)
# 'data.frame': 15 obs. of 4 variables:
# $ one : num 0 0.184 -0.836 0 0.33 ...
# $ two : chr "M" "O" "L" "E" ...
# $ three: num 0.8042 -0.0571 0.5036 99 99 ...
# $ four : num 0.892 0 0.39 0 0.961 ...
columns_to_change <- c("one","four")
dat[columns_to_change] <- lapply(dat[columns_to_change], function(x) replace(x, is.na(x), 0))
columns_to_change <- c("two")
dat[columns_to_change] <- lapply(dat[columns_to_change], function(x) replace(x, is.na(x), "none"))
columns_to_change <- c("three")
dat[columns_to_change] <- lapply(dat[columns_to_change], function(x) replace(x, is.na(x), 99))
L <- list(
list(cols = c("one","four"), replacement = 0),
list(cols = c("two"), replacement = "none"),
list(cols = c("three"), replacement = 99)
)
for (pars in L) {
dat[pars$cols] <- lapply(
dat[pars$cols]
, function(x) replace(x, is.na(x), pars$replacement)
)
}
naSwitcher <- function(indf, cols, naType) {
if (length(cols) != length(naType)) stop("Something's wrong")
indf[cols] <- lapply(seq_along(indf[cols]), function(x) {
switch(naType[x],
"0" = { indf[cols[x]][is.na(indf[cols[x]])] <- 0; indf[cols[x]] },
"none" = { indf[cols[x]][is.na(indf[cols[x]])] <- "none"; indf[cols[x]] },
"99" = { indf[cols[x]][is.na(indf[cols[x]])] <- 99; indf[cols[x]] },
"NA" = { indf[cols[x]] },
stop("naType must be either '0', 'none', '99', or 'NA'"))
})
indf
}
head(naSwitcher(dat, 1:4, c("0", "none", "99", "99")))
# one two three four
# 1 0.0000000 M 0.80418951 0.8921983
# 2 0.1836433 O -0.05710677 99.0000000
# 3 -0.8356286 L 0.50360797 0.3899895
# 4 0.0000000 E 99.00000000 99.0000000
# 5 0.3295078 S 99.00000000 0.9606180
# 6 -0.8204684 none -1.28459935 0.4346595