Eri*_*ail 13 r base missing-features missing-data
我有兴趣指定缺失值的类型.我有不同类型的丢失的数据,我试图将这些值编码为R中缺少,但我正在寻找一个解决方案,我仍然可以区分它们.
假设我有一些看起来像这样的数据,
set.seed(667)
df <- data.frame(a = sample(c("Don't know/Not sure","Unknown","Refused","Blue", "Red", "Green"), 20, rep=TRUE), b = sample(c(1, 2, 3, 77, 88, 99), 10, rep=TRUE), f = round(rnorm(n=10, mean=.90, sd=.08), digits = 2), g = sample(c("C","M","Y","K"), 10, rep=TRUE) ); df
# a b f g
# 1 Unknown 2 0.78 M
# 2 Refused 2 0.87 M
# 3 Red 77 0.82 Y
# 4 Red 99 0.78 Y
# 5 Green 77 0.97 M
# 6 Green 3 0.99 K
# 7 Red 3 0.99 Y
# 8 Green 88 0.84 C
# 9 Unknown 99 1.08 M
# 10 Refused 99 0.81 C
# 11 Blue 2 0.78 M
# 12 Green 2 0.87 M
# 13 Blue 77 0.82 Y
# 14 Don't know/Not sure 99 0.78 Y
# 15 Unknown 77 0.97 M
# 16 Refused 3 0.99 K
# 17 Blue 3 0.99 Y
# 18 Green 88 0.84 C
# 19 Refused 99 1.08 M
# 20 Red 99 0.81 C
Run Code Online (Sandbox Code Playgroud)
如果我现在制作两个表,我的缺失值("Don't know/Not sure","Unknown","Refused"和77, 88, 99)作为常规数据包含在内,
table(df$a,df$g)
# C K M Y
# Blue 0 0 1 2
# Don't know/Not sure 0 0 0 1
# Green 2 1 2 0
# Red 1 0 0 3
# Refused 1 1 2 0
# Unknown 0 0 3 0
Run Code Online (Sandbox Code Playgroud)
和
table(df$b,df$g)
# C K M Y
# 2 0 0 4 0
# 3 0 2 0 2
# 77 0 0 2 2
# 88 2 0 0 0
# 99 2 0 2 2
Run Code Online (Sandbox Code Playgroud)
我现在将三个因子级别重新编码"Don't know/Not sure","Unknown","Refused"为<NA>
is.na(df[,c("a")]) <- df[,c("a")]=="Don't know/Not sure"|df[,c("a")]=="Unknown"|df[,c("a")]=="Refused"
Run Code Online (Sandbox Code Playgroud)
并删除空的级别
df$a <- factor(df$a)
Run Code Online (Sandbox Code Playgroud)
并且使用数值77, 88,和完成相同的操作99
is.na(df) <- df=="77"|df=="88"|df=="99"
table(df$a, df$g, useNA = "always")
# C K M Y <NA>
# Blue 0 0 1 2 0
# Green 2 1 2 0 0
# Red 1 0 0 3 0
# <NA> 1 1 5 1 0
table(df$b,df$g, useNA = "always")
# C K M Y <NA>
# 2 0 0 4 0 0
# 3 0 2 0 2 0
# <NA> 4 0 4 4 0
Run Code Online (Sandbox Code Playgroud)
现在丢失的类别被重新编码,NA但它们都被集中在一起.是否有一种方法可以将某些东西重新编码为缺失,但保留原始值?我希望R线程"Don't know/Not sure","Unknown","Refused"并且77, 88, 99缺少,但我希望能够在变量中保留信息.
A5C*_*2T1 19
据我所知,base R没有内置的方法来处理不同的NA类型.(编辑:它:NA_integer_,NA_real_,NA_complex_,和NA_character见?base::NA.)
一种选择是使用这样做的包,例如" memisc ".这是一些额外的工作,但它似乎做你正在寻找的.
这是一个例子:
首先,你的数据.我已经制作了一份副本,因为我们将对数据集进行一些非常重要的更改,并且备份总是很好.
set.seed(667)
df <- data.frame(a = sample(c("Don't know/Not sure", "Unknown",
"Refused", "Blue", "Red", "Green"),
20, replace = TRUE),
b = sample(c(1, 2, 3, 77, 88, 99), 10,
replace = TRUE),
f = round(rnorm(n = 10, mean = .90, sd = .08),
digits = 2),
g = sample(c("C", "M", "Y", "K"), 10,
replace = TRUE))
df2 <- df
Run Code Online (Sandbox Code Playgroud)
让因子变量"a":
df2$a <- factor(df2$a,
levels = c("Blue", "Red", "Green",
"Don't know/Not sure",
"Refused", "Unknown"),
labels = c(1, 2, 3, 77, 88, 99))
Run Code Online (Sandbox Code Playgroud)
加载"memisc"库:
library(memisc)
Run Code Online (Sandbox Code Playgroud)
现在,将变量"a"和"b"转换item为"memisc"中的s:
df2$a <- as.item(as.character(df2$a),
labels = structure(c(1, 2, 3, 77, 88, 99),
names = c("Blue", "Red", "Green",
"Don't know/Not sure",
"Refused", "Unknown")),
missing.values = c(77, 88, 99))
df2$b <- as.item(df2$b,
labels = c(1, 2, 3, 77, 88, 99),
missing.values = c(77, 88, 99))
Run Code Online (Sandbox Code Playgroud)
通过这样做,我们有了一种新的数据类型.比较以下内容:
as.factor(df2$a)
# [1] <NA> <NA> Red Red Green Green Red Green <NA> <NA> Blue
# [12] Green Blue <NA> <NA> <NA> Blue Green <NA> Red
# Levels: Blue Red Green
as.factor(include.missings(df2$a))
# [1] *Unknown *Refused Red
# [4] Red Green Green
# [7] Red Green *Unknown
# [10] *Refused Blue Green
# [13] Blue *Don't know/Not sure *Unknown
# [16] *Refused Blue Green
# [19] *Refused Red
# Levels: Blue Red Green *Don't know/Not sure *Refused *Unknown
Run Code Online (Sandbox Code Playgroud)
我们可以使用此信息创建以您描述的方式运行的表,同时保留所有原始信息.
table(as.factor(include.missings(df2$a)), df2$g)
#
# C K M Y
# Blue 0 0 1 2
# Red 1 0 0 3
# Green 2 1 2 0
# *Don't know/Not sure 0 0 0 1
# *Refused 1 1 2 0
# *Unknown 0 0 3 0
table(as.factor(df2$a), df2$g)
#
# C K M Y
# Blue 0 0 1 2
# Red 1 0 0 3
# Green 2 1 2 0
table(as.factor(df2$a), df2$g, useNA="always")
#
# C K M Y <NA>
# Blue 0 0 1 2 0
# Red 1 0 0 3 0
# Green 2 1 2 0 0
# <NA> 1 1 5 1 0
Run Code Online (Sandbox Code Playgroud)
具有缺失数据的数字列的表行为相同.
table(as.factor(include.missings(df2$b)), df2$g)
#
# C K M Y
# 1 0 0 0 0
# 2 0 0 4 0
# 3 0 2 0 2
# *77 0 0 2 2
# *88 2 0 0 0
# *99 2 0 2 2
table(as.factor(df2$b), df2$g, useNA="always")
#
# C K M Y <NA>
# 1 0 0 0 0 0
# 2 0 0 4 0 0
# 3 0 2 0 2 0
# <NA> 4 0 4 4 0
Run Code Online (Sandbox Code Playgroud)
作为奖励,你可以获得生成好的设施codebook:
> codebook(df2$a)
========================================================================
df2$a
------------------------------------------------------------------------
Storage mode: character
Measurement: nominal
Missing values: 77, 88, 99
Values and labels N Percent
1 'Blue' 3 25.0 15.0
2 'Red' 4 33.3 20.0
3 'Green' 5 41.7 25.0
77 M 'Don't know/Not sure' 1 5.0
88 M 'Refused' 4 20.0
99 M 'Unknown' 3 15.0
Run Code Online (Sandbox Code Playgroud)
不过,我也建议你阅读评论从@ Maxim.K什么真正构成缺失值.
要保留原始值,可以创建用于编码NA信息的新列,例如:
df <- transform(df,b.na = ifelse(b %in% c('77','88','99'),NA,b))
df <- transform(df,a.na = ifelse(a %in%
c("Don't know/Not sure","Unknown","Refused"),NA,a))
Run Code Online (Sandbox Code Playgroud)
然后你可以做这样的事情:
table(df$b.na , df$g)
C K M Y
2 0 0 4 0
3 0 2 0 2
Run Code Online (Sandbox Code Playgroud)
不创建新列的另一个选项是使用这样的exclude选项将非期望值设置为NULL(不同的缺失值)
table(df$a,df$g,
exclude=c('77','88','99',"Don't know/Not sure","Unknown","Refused"))
C K M Y
Blue 0 0 1 2
Green 2 1 2 0
Red 1 0 0 3
Run Code Online (Sandbox Code Playgroud)
您可以定义一些全局常量(即使它不是建议的)来对"缺失值"进行分组,并在程序的其余部分中使用它们.像这样的东西:
B_MISSING <- c('77','88','99')
A_MISSING <- c("Don't know/Not sure","Unknown","Refused")
Run Code Online (Sandbox Code Playgroud)
如果您愿意坚持使用数值,那么NA, Inf, -Inf, 和NaN可用于不同的缺失值。然后您可以使用is.finite它们来区分它们和正常值:
x <- c(NA, Inf, -Inf, NaN, 1)
is.finite(x)
## [1] FALSE FALSE FALSE FALSE TRUE
Run Code Online (Sandbox Code Playgroud)
is.infinite,is.nan并is.na在这里也是有用的。
我们可以有一个特殊的打印功能,以更有意义的方式显示它们,甚至创建一个特殊的类,但即使没有,上面也会将数据划分为有限值和多个非有限值。