首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >替换因子列中的<NA>

替换因子列中的<NA>
EN

Stack Overflow用户
提问于 2016-08-24 14:46:30
回答 6查看 56.6K关注 0票数 41

我希望用有效值替换“因素”列中的<NA>值。但我找不到办法。此示例仅用于演示。原始数据来自我必须处理的一个外国csv文件。

代码语言:javascript
运行
复制
df <- data.frame(a=sample(0:10, size=10, replace=TRUE),
                 b=sample(20:30, size=10, replace=TRUE))
df[df$a==0,'a'] <- NA
df$a <- as.factor(df$a)

可能是这样的

代码语言:javascript
运行
复制
      a  b
1     1 29
2     2 23
3     3 23
4     3 22
5     4 28
6  <NA> 24
7     2 21
8     4 25
9  <NA> 29
10    3 24

现在,我想用一个数字替换<NA>值。

代码语言:javascript
运行
复制
df[is.na(df$a), 'a'] <- 88
In `[<-.factor`(`*tmp*`, iseq, value = c(88, 88)) :
  invalid factor level, NA generated

我想我忽略了一个关于因素的基本R概念。我是吗?我不明白它为什么不起作用。我认为invalid factor level意味着88在这个因素中不是一个有效的水平,对吗?所以我必须告诉因子列还有另一个层次吗?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2016-08-24 14:55:04

1) addNA,如果fac是一个因子,则addNA(fac)是相同的因素,但是NA作为一个级别添加。请参阅?addNA

强制NA水平达到88:

代码语言:javascript
运行
复制
facna <- addNA(fac)
levels(facna) <- c(levels(fac), 88)

给予:

代码语言:javascript
运行
复制
> facna
 [1] 1  2  3  3  4  88 2  4  88 3 
Levels: 1 2 3 4 88

1a) --它可以写成一行,如下所示:

代码语言:javascript
运行
复制
`levels<-`(addNA(fac), c(levels(fac), 88))

2)因子它也可以在一行中使用factor的各种参数完成,如下所示:

代码语言:javascript
运行
复制
factor(fac, levels = levels(addNA(fac)), labels = c(levels(fac), 88), exclude = NULL)

2a)或等效:

代码语言:javascript
运行
复制
factor(fac, levels = c(levels(fac), NA), labels = c(levels(fac), 88), exclude = NULL)

3)如果是,另一种方法是:

代码语言:javascript
运行
复制
factor(ifelse(is.na(fac), 88, paste(fac)), levels = c(levels(fac), 88))

4) forcatforcat包具有如下功能:

代码语言:javascript
运行
复制
library(forcats)

fct_explicit_na(fac, "88")
## [1] 1  2  3  3  4  88 2  4  88 3 
## Levels: 1 2 3 4 88

注意:--我们使用以下方法输入fac

代码语言:javascript
运行
复制
fac <- structure(c(1L, 2L, 3L, 3L, 4L, NA, 2L, 4L, NA, 3L), .Label = c("1", 
"2", "3", "4"), class = "factor")

更新:已经改进(1)并添加了(1a)。随后添加(4)。

票数 71
EN

Stack Overflow用户

发布于 2017-09-30 06:20:58

其他办法是:

代码语言:javascript
运行
复制
#check levels
levels(df$a)
#[1] "3"  "4"  "7"  "9"  "10"

#add new factor level. i.e 88 in our example
df$a = factor(df$a, levels=c(levels(df$a), 88))

#convert all NA's to 88
df$a[is.na(df$a)] = 88

#check levels again
levels(df$a)
#[1] "3"  "4"  "7"  "9"  "10" "88"
票数 8
EN

Stack Overflow用户

发布于 2020-04-25 13:19:45

我也有类似的问题,我想补充一下我认为最务实(也是最整洁)的解决方案:

将该列转换为character列,使用mutate和简单的ifelse-statement将NA值更改为您希望的因子级别(我选择了"None"),将其转换回factor列:

代码语言:javascript
运行
复制
df %>% mutate(
a = as.character(a),
a = ifelse(is.na(a), "None", a),
a = as.factor(a)
)

清洁和无痛,因为当NA值出现在factor列中时,实际上不必使用它们。您绕过了奇怪之处,最终得到了一个干净的factor变量。

另外,针对下面关于多列的注释:您可以将语句包装在一个函数中,并使用mutate_if选择所有因素变量,或者,如果您知道所关注的列的名称,则可以使用mutate_at应用该函数:

代码语言:javascript
运行
复制
replace_factor_na <- function(x){
  x <- as.character(x)
  x <- if_else(is.na(x), "None", x)
  x <- as.factor(x)
}

df <- df %>%
  mutate_if(is.factor, replace_factor_na)
票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39126537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档