【问题标题】:Generate Dummy Variables From Data Frame从数据框生成虚拟变量
【发布时间】:2018-02-02 15:06:52
【问题描述】:

我有一个 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

任何想法如何实现这一目标?谢谢!

【问题讨论】:

  • ?sample()
  • 您需要虚拟变量或值?标题具有误导性。您需要对输出进行更多解释。 0 和 1 是随机的或者它们有一些条件
  • 目标是创建一个 data.frame,如果列表中存在例如 145540,则出现值 1,否则为 0。这与随机抽样无关。

标签: r dataframe dummy-variable


【解决方案1】:

只需使用stacktable

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)

【讨论】:

  • 您将如何使用 Spark 集群(例如 SparklyR)解决此问题?
【解决方案2】:

我的回答有点笨拙,但这里是:

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

【讨论】:

    【解决方案3】:

    你可以使用%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
    

    【讨论】:

      猜你喜欢
      • 2020-06-22
      • 2017-05-05
      • 1970-01-01
      • 2018-05-28
      • 2012-08-10
      • 1970-01-01
      相关资源
      最近更新 更多