从数据框生成虚拟变量
Generate Dummy Variables From Data Frame
我有一个 data.frame
具有以下属性:
list1 <- c(145540,145560, 157247, 145566)
list2 <- c(166927, NA, NA, NA)
list3 <- c(145592, 145560, 145566, NA)
df <- data.frame(list1, list2, list3)
我想为每个包含的 ID 生成一个虚拟变量。结果应该是这样的。
list, 145540, 145560, 145566,145592,157247,166927 (= all possible ids in the data)
list1, 1, 1, 1, 0, 1, 0
list2, 0, 0, 0, 0, 0, 1
list3, 0, 1, 1, 1, 0, 0
有什么实现方法吗?谢谢!
您可以使用 %in%
:
list %in% list1 + 0
# [1] 1 1 1 0 1 0
请注意,您对 list1 的回答有错别字,因为 145592 不在 list1 中,但 157247 在。 + 0
将 TRUE/FALSE 转换为 1/0。您可以使用 sapply()
:
处理整个数据帧
t(sapply(df, function(x) list %in% x + 0))
# [,1] [,2] [,3] [,4] [,5] [,6]
# list1 1 1 1 0 1 0
# list2 0 0 0 0 0 1
# list3 0 1 1 1 0 0
只需使用 stack
和 table
:
t(table(stack(df)))
## values
## ind 145540 145560 145566 145592 157247 166927
## list1 1 1 1 0 1 0
## list2 0 0 0 0 0 1
## list3 0 1 1 1 0 0
或者,"data.table":
library(data.table)
melt(as.data.table(df), measure.vars = names(df), na.rm = TRUE)[
, dcast(.SD, variable ~ value, fun = length)]
## variable 145540 145560 145566 145592 157247 166927
## 1: list1 1 1 1 0 1 0
## 2: list2 0 0 0 0 0 1
## 3: list3 0 1 1 1 0 0
或 "tidyverse":
library(tidyverse)
df %>%
gather(var, col, everything(), na.rm = TRUE) %>%
mutate(val = 1) %>%
spread(col, val, fill = 0)
或 "qdapTools":
mtabulate(df)
我的回答有点笨拙,但在这里:
all.vals <- na.omit(unique(unlist(df))) ## get full set of values
使用 for
循环更清晰:
df2 <- list()
for (i in seq_along(df))
df2[[i]] <-
sapply(all.vals,
function(x) as.numeric(x %in% df[[i]]))
names(df2) <- names(df)
## add labels as the first column:
df2 <- data.frame(all.vals,df2)
结果:
all.vals list1 list2 list3
1 145540 1 0 0
2 145560 1 0 1
3 157247 1 0 0
4 145566 1 0 1
5 166927 0 1 0
6 145592 0 0 1
我有一个 data.frame
具有以下属性:
list1 <- c(145540,145560, 157247, 145566)
list2 <- c(166927, NA, NA, NA)
list3 <- c(145592, 145560, 145566, NA)
df <- data.frame(list1, list2, list3)
我想为每个包含的 ID 生成一个虚拟变量。结果应该是这样的。
list, 145540, 145560, 145566,145592,157247,166927 (= all possible ids in the data)
list1, 1, 1, 1, 0, 1, 0
list2, 0, 0, 0, 0, 0, 1
list3, 0, 1, 1, 1, 0, 0
有什么实现方法吗?谢谢!
您可以使用 %in%
:
list %in% list1 + 0
# [1] 1 1 1 0 1 0
请注意,您对 list1 的回答有错别字,因为 145592 不在 list1 中,但 157247 在。 + 0
将 TRUE/FALSE 转换为 1/0。您可以使用 sapply()
:
t(sapply(df, function(x) list %in% x + 0))
# [,1] [,2] [,3] [,4] [,5] [,6]
# list1 1 1 1 0 1 0
# list2 0 0 0 0 0 1
# list3 0 1 1 1 0 0
只需使用 stack
和 table
:
t(table(stack(df)))
## values
## ind 145540 145560 145566 145592 157247 166927
## list1 1 1 1 0 1 0
## list2 0 0 0 0 0 1
## list3 0 1 1 1 0 0
或者,"data.table":
library(data.table)
melt(as.data.table(df), measure.vars = names(df), na.rm = TRUE)[
, dcast(.SD, variable ~ value, fun = length)]
## variable 145540 145560 145566 145592 157247 166927
## 1: list1 1 1 1 0 1 0
## 2: list2 0 0 0 0 0 1
## 3: list3 0 1 1 1 0 0
或 "tidyverse":
library(tidyverse)
df %>%
gather(var, col, everything(), na.rm = TRUE) %>%
mutate(val = 1) %>%
spread(col, val, fill = 0)
或 "qdapTools":
mtabulate(df)
我的回答有点笨拙,但在这里:
all.vals <- na.omit(unique(unlist(df))) ## get full set of values
使用 for
循环更清晰:
df2 <- list()
for (i in seq_along(df))
df2[[i]] <-
sapply(all.vals,
function(x) as.numeric(x %in% df[[i]]))
names(df2) <- names(df)
## add labels as the first column:
df2 <- data.frame(all.vals,df2)
结果:
all.vals list1 list2 list3
1 145540 1 0 0
2 145560 1 0 1
3 157247 1 0 0
4 145566 1 0 1
5 166927 0 1 0
6 145592 0 0 1