R - 多级变量到假人

R - Multilevel Variable into Dummies

我觉得这应该更容易。

假设我有一个包含 "multivalued" 项的字段,例如电影的类型。

我想将它们分解成虚拟对象,其中包含多个项目的行每行都有一个虚拟对象。

我该如何以一种方便的方式做到这一点?

错误的 R 示例:

library(tidyverse)

data <- tribble(
  ~column,
  "var1",
  "var1 / var2",
  "var2",
  "var3",
  "var1 / var3",
  "var2 / var3"
)

data %>%
  separate(column, into = c("item1", "item2"), sep = " / ", fill = "right") %>%
  mutate_each(funs(factor(., levels = c("var1", "var2", "var3")))) %>%
  mutate(row = as.factor(row_number())) ->
  intermediate

head(intermediate)
#> # A tibble: 6 × 3
#>    item1  item2    row
#>   <fctr> <fctr> <fctr>
#> 1   var1     NA      1
#> 2   var1   var2      2
#> 3   var2     NA      3
#> 4   var3     NA      4
#> 5   var1   var3      5
#> 6   var2   var3      6

v1 <- xtabs( ~ row + item1, data = intermediate)
v2 <- xtabs( ~ row + item2, data = intermediate)

combined <- v1 + v2

combined
#>    item1
#> row var1 var2 var3
#>   1    1    0    0
#>   2    1    1    0
#>   3    0    1    0
#>   4    0    0    1
#>   5    1    0    1
#>   6    0    1    1

感觉真的不像 R。

Python 例子

这在 Python 和 sklearnDictVectorizer 中很容易做到。例如:

import pandas as pd
from sklearn.feature_extraction import DictVectorizer

d = [
    "var1",
    "var1 / var2",
    "var2",
    "var3",
    "var1 / var3",
    "var2 / var3"
]

data = pd.DataFrame(d, columns = ["column"])

col = data.column.str.split(" / ")
col = col.apply(lambda row: {key: 1 for key in row})

transformer = DictVectorizer()
transformer.fit_transform(col).todense()

#> matrix([[ 1.,  0.,  0.],
#>         [ 1.,  1.,  0.],
#>         [ 0.,  1.,  0.],
#>         [ 0.,  0.,  1.],
#>         [ 1.,  0.,  1.],
#>         [ 0.,  1.,  1.]])

我真的只是在寻找 R-land 中的 "tidy" 等价物。

你可以使用splitstackshape

  x<-c("var1",
       "var1 / var2",
       "var2",
       "var3",
       "var1 / var3",
       "var2 / var3"
  )

library(splitstackshape)

splitstackshape:::charMat(strsplit(x, " / "), 0)


     var1 var2 var3
[1,]    1    0    0
[2,]    1    1    0
[3,]    0    1    0
[4,]    0    0    1
[5,]    1    0    1
[6,]    0    1    1