将 missing/non-missing 值更改为二进制 (0/1)
Change missing/non-missing values to binary (0/1)
我的数据集是:
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
我想按如下方式将数据集更改为二进制数据集
观察到的非NA
值-> 1
缺失,NA
个值 -> 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)
.
你可以只使用 !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。
基准测试总结:
- 如果您追求的是纯粹的速度,请选择 "data.table" 方法。
- 如果您想要 base R 中的高效代码,
as.integer
和 +
实际上是并驾齐驱的,所以我想您知道我的建议在哪里。
我们可以用+
包裹逻辑矩阵,将其转换为二进制。应该也很快。
+(!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
我的数据集是:
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
我想按如下方式将数据集更改为二进制数据集
观察到的非NA
值-> 1
缺失,NA
个值 -> 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)
.
你可以只使用 !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。
基准测试总结:
- 如果您追求的是纯粹的速度,请选择 "data.table" 方法。
- 如果您想要 base R 中的高效代码,
as.integer
和+
实际上是并驾齐驱的,所以我想您知道我的建议在哪里。
我们可以用+
包裹逻辑矩阵,将其转换为二进制。应该也很快。
+(!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