在 R 中,是否有任何方法可以填充 NA 并保留变量属性?
In R, is the any way can fill NA and keep variable attribute?
使用zoo::na.fill(0)
可以用0填充所有的NA,但是这样会改变变量属性,
例如,变量 amount
的属性在数据帧 md 中是 num
,在 zoo::na.fill(0)
之后属性更改为 chr
。有没有什么方法可以像na.fill
一样简单的填充na并保持变量属性?
md <- data.frame(cat=c('a','b','d',NA,'E',NA),
subcat=c('A','C',NA,NA,NA,'D'),
amount=c(1,2,NA,5,NA,8))
md %>% zoo::na.fill(0)
这是一个不使用 zoo 的解决方案。
library(dplyr)
md2 <- md %>%
mutate(across(where(is.factor), as.character)) %>%
mutate(across(where(is.character), function(x) { replace(x, is.na(x), "0") } )) %>%
mutate(across(where(is.numeric), function(x) { replace(x, is.na(x), 0) } )) %>%
mutate(across(where(is.character), as.factor))
如果你愿意,你可以把它包装成一个自定义的函数,像zoo的fill-na方法一样方便使用,例如
FillNA <- function(df){
df2 <- df %>%
mutate(across(where(is.factor), as.character)) %>%
mutate(across(where(is.character), function(x) { replace(x, is.na(x), "0") } )) %>%
mutate(across(where(is.numeric), function(x) { replace(x, is.na(x), 0) } )) %>%
mutate(across(where(is.character), as.factor))
return(df2)
}
此处验证类型:
> str(md)
'data.frame': 6 obs. of 3 variables:
$ cat : Factor w/ 4 levels "a","b","d","E": 1 2 3 NA 4 NA
$ subcat: Factor w/ 3 levels "A","C","D": 1 2 NA NA NA 3
$ amount: num 1 2 NA 5 NA 8
str(FillNA(md))
'data.frame': 6 obs. of 3 variables:
$ cat : Factor w/ 5 levels "0","a","b","d",..: 2 3 4 1 5 1
$ subcat: Factor w/ 4 levels "0","A","C","D": 2 3 1 1 1 4
$ amount: num 1 2 0 5 0 8
使用zoo::na.fill(0)
可以用0填充所有的NA,但是这样会改变变量属性,
例如,变量 amount
的属性在数据帧 md 中是 num
,在 zoo::na.fill(0)
之后属性更改为 chr
。有没有什么方法可以像na.fill
一样简单的填充na并保持变量属性?
md <- data.frame(cat=c('a','b','d',NA,'E',NA),
subcat=c('A','C',NA,NA,NA,'D'),
amount=c(1,2,NA,5,NA,8))
md %>% zoo::na.fill(0)
这是一个不使用 zoo 的解决方案。
library(dplyr)
md2 <- md %>%
mutate(across(where(is.factor), as.character)) %>%
mutate(across(where(is.character), function(x) { replace(x, is.na(x), "0") } )) %>%
mutate(across(where(is.numeric), function(x) { replace(x, is.na(x), 0) } )) %>%
mutate(across(where(is.character), as.factor))
如果你愿意,你可以把它包装成一个自定义的函数,像zoo的fill-na方法一样方便使用,例如
FillNA <- function(df){
df2 <- df %>%
mutate(across(where(is.factor), as.character)) %>%
mutate(across(where(is.character), function(x) { replace(x, is.na(x), "0") } )) %>%
mutate(across(where(is.numeric), function(x) { replace(x, is.na(x), 0) } )) %>%
mutate(across(where(is.character), as.factor))
return(df2)
}
此处验证类型:
> str(md)
'data.frame': 6 obs. of 3 variables:
$ cat : Factor w/ 4 levels "a","b","d","E": 1 2 3 NA 4 NA
$ subcat: Factor w/ 3 levels "A","C","D": 1 2 NA NA NA 3
$ amount: num 1 2 NA 5 NA 8
str(FillNA(md))
'data.frame': 6 obs. of 3 variables:
$ cat : Factor w/ 5 levels "0","a","b","d",..: 2 3 4 1 5 1
$ subcat: Factor w/ 4 levels "0","A","C","D": 2 3 1 1 1 4
$ amount: num 1 2 0 5 0 8