R 将NAs更改为';无';,0或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),

我有一个包含50列的数据集,我想编写一个函数,为存在NAs的50列中的每一列分配一个零、“无”或99(如我指定的)。我可以为每一列编写一行代码(在我下面的示例中),但我认为一定有一种方法可以通过一个函数来实现这一点,该函数可以减少我需要编写的代码量

下面是一个有四列的示例

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