我的数据集是:
df=data.frame(x=c(1,4,6,NA,7,NA,9,10,4,NA),
y=c(10,12,NA,NA,14,18,20,15,12,17),
z=c(225,198,NA,NA,NA,130,NA,200,NA,99))
df
x y z
1 1 10 225
2 4 12 198
3 6 NA NA
4 NA NA NA
5 7 14 NA
6 NA 18 130
7 9 20 NA
8 10 15 200
9 4 12 NA
10 NA 17 99
我想将数据集更改为二进制数据集,如下所示
观察到的元素= 1
遗漏元素= 0
x y z
1 1 1 1
2 1 1 1
3 1 0 0
4 0 0 0
5 1 1 0
6 0 1 1
7 1 1 0
8 1 1 1
9 1 1 0
10 0 1 1
如何在R中执行此操作?
我的培训代码是ifelse(df=NA , 0 ,1)
。
答案 0 :(得分:5)
您可以使用!is.na
,如下所示:
# df[] <- as.numeric(!is.na(df)) # <- Original answer
df[] <- as.integer(!is.na(df)) # <- Thanks @docendodiscimus
df
# x y z
# 1 1 1 1
# 2 1 1 1
# 3 1 0 0
# 4 0 0 0
# 5 1 1 0
# 6 0 1 1
# 7 1 1 0
# 8 1 1 1
# 9 1 1 0
# 10 0 1 1
如果关注效率,可以尝试使用“data.table”包:
as.data.table(df)[, lapply(.SD, function(x) as.numeric(!is.na(x)))]
# x y z
# 1: 1 1 1
# 2: 1 1 1
# 3: 1 0 0
# 4: 0 0 0
# 5: 1 1 0
# 6: 0 1 1
# 7: 1 1 0
# 8: 1 1 1
# 9: 1 1 0
# 10: 0 1 1
或者在替换时分配:
as.data.table(df)[, (names(df)) := lapply(.SD, function(x) as.numeric(!is.na(x)))][]
<强> 更新 强>
如果有人对进一步的基准测试感兴趣,您可以查看this Gist。
基准测试摘要:
as.integer
和+
几乎是一对一的,那么我想您知道我的建议会在哪里。答案 1 :(得分:1)
我们可以在逻辑矩阵上用+
换行以将其转换为二进制。它也应该非常快。
+(!is.na(df))
# x y z
# [1,] 1 1 1
# [2,] 1 1 1
# [3,] 1 0 0
# [4,] 0 0 0
# [5,] 1 1 0
# [6,] 0 1 1
# [7,] 1 1 0
# [8,] 1 1 1
# [9,] 1 1 0
#[10,] 0 1 1
dplyr
选项
library(dplyr)
df %>%
mutate_each(funs(+(!is.na(.))) )
# x y z
#1 1 1 1
#2 1 1 1
#3 1 0 0
#4 0 0 0
#5 1 1 0
#6 0 1 1
#7 1 1 0
#8 1 1 1
#9 1 1 0
#10 0 1 1
set.seed(24)
df <- as.data.frame(matrix(sample(c(NA, 1:20), 5000*5000,
replace=TRUE), ncol=5000))
system.time(as.numeric(!is.na(df)))
# user system elapsed
# 0.64 0.09 0.73
system.time(+(!is.na(df)))
# user system elapsed
# 0.42 0.11 0.53