【问题标题】:One hot coding a data-frame in R在 R 中对数据帧进行热编码
【发布时间】:2016-10-23 01:39:09
【问题描述】:

考虑一个类似于所示的数据框df1

ID EDUCATION   OCCUPATION      BINARY_VAR
1  Undergrad   Student              1
2  Grad        Business Owner       1
3  Undergrad   Unemployed           0
4  PhD         Other                1

您可以使用下面的 R 代码创建自己的随机 df1

ID <- c(1:4)
EDUCATION <- sample (c('Undergrad', 'Grad', 'PhD'), 4, rep = TRUE)
OCCUPATION <- sample (c('Student', 'Business Owner', 'Unemployed', 'Other'), 4, rep = FALSE)
BINARY_VAR <- sample(c(0, 1), 4, rep = TRUE)
df1 <- data.frame(ID, EDUCATION, OCCUPATION, BINARY_VAR)

# Convert to factor
df1[, names(df1)] <- lapply(df1[, names(df1)] , factor)

由此,我需要派生另一个看起来像这样的数据框df2

ID Undergrad Grad PhD Student Business Owner Unemployed Other BINARY_VAR
1      1      0    0     1           0           0        0       1
2      1      1    0     0           1           0        0       1
3      1      0    0     0           0           1        0       0
4      1      1    1     0           0           0        1       1

您一定已经注意到PhD 的级别,EDUCATION 下的其他因素级别也适用,因为EDUCATION 是该ID 的最高教育级别。然而,这是次要目标。

我似乎无法找到一种方法获得一个数据框,其中每一列都给出对应于其父数据框中各个因素水平的真值in R 中是否有可以提供帮助的包?或者也许是一种编码方式?

我可以使用melt 执行此操作吗?

我通读了previously asked question(s),看起来相似,但它们处理的是出现频率。


编辑:

根据Sumedh 的建议,一种方法是使用caret 中的dummyVars

dummies <- dummyVars(ID ~ ., data = df1)
df2 <- data.frame(predict(dummies, newdata = df1))
df2 <- df2 [1:7]

【问题讨论】:

  • 对于您的主要目标,您可以使用 dummyVars from caret topepo.github.io/caret/preprocess.html
  • 对于博士,您可以使用df$Grad[df$PhD == 1] &lt;- 1df$Undergrad[df$PhD == 1] &lt;- 1。也许有更好的方法。
  • 成功了!关于如何获得实际目标的任何想法?

标签: r dataframe packages data-cleaning


【解决方案1】:

tidyrdplyr 结合 base table() 函数应该可以工作:

ID <- c(1:4)
EDUCATION <- c('Undergrad', 'Grad', 'PhD', 'Undergrad')
OCCUPATION <- c('Student', 'Business Owner', 'Unemployed', 'Other')
BINARY_VAR <- sample(c(0, 1), 4, rep = TRUE)
df1 <- data.frame(ID, EDUCATION, OCCUPATION, BINARY_VAR)

# Convert to factor
df1[, names(df1)] <- lapply(df1[, names(df1)] , factor)

library(dplyr)
library(tidyr)

edu<-as.data.frame(table(df1[,1:2])) %>% spread(EDUCATION, Freq)

for(i in 1:nrow(edu))
  if(edu[i,]$PhD == 1) 
    edu[i,]$Undergrad <-edu[i,]$Grad <-1

truth_table<-merge(edu,
      as.data.frame(table(df1[,c(1,3)])) %>% spread(OCCUPATION, Freq),
      by = "ID")

truth_table$BINARY_VAR<-df1$BINARY_VAR
truth_table

ID Grad PhD Undergrad Business Owner Other Student Unemployed BINARY_VAR
1    0   0         1              0     0       1          0          1
2    1   0         0              1     0       0          0          1
3    1   1         1              0     0       0          1          0
4    0   0         1              0     1       0          0          1

编辑:添加了一个for 循环以更新PhD 下的教育水平,灵感来自@ Sumedh 早期的建议。

【讨论】:

  • @Sumedh 的解决方案有效,除了 - 原始数据有 12 个因子级别,所以也许我必须创建一个函数(有点)以迭代方式在级别上进行。此外,还有大约 160,000 行...
猜你喜欢
  • 1970-01-01
  • 2017-05-02
  • 2022-01-18
  • 1970-01-01
  • 2018-04-08
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多