将带有管道分隔数据的列转换为虚拟变量

时间:2016-09-13 02:51:03

标签: r delimiter

我有兴趣获取data.frame的列,其中列中的值是管道分隔的,并从管道分隔的值创建虚拟变量。

例如:

我们假设我们从

开始
df = data.frame(a = c("Ben|Chris|Jim", "Ben|Greg|Jim|", "Jim|Steve|Ben"))

> df
              a
1 Ben|Chris|Jim
2 Ben|Greg|Jim
3 Jim|Steve|Ben

我有兴趣以:

结束
df2 = data.frame(Ben = c(1, 1, 1), Chris = c(1, 0, 0), Jim = c(1, 1, 1), Greg = c(0, 1, 0), 
                 Steve = c(0, 0, 1))
> df2
  Ben Chris Jim Greg Steve
1   1     1   1    0     0
2   1     0   1    1     0
3   1     0   1    0     1

我事先并不知道该领域有多少潜在价值。在上面的例子中,变量" a"可以包含1个值或10个值。假设它是一个合理的数字(即< 100可能的值)。

有什么好方法吗?

4 个答案:

答案 0 :(得分:7)

以下是使用dplyrtidyr的一个选项:

library(dplyr)
library(tidyr)
df %>% tibble::rownames_to_column(var = "id") %>% 
       mutate(a = strsplit(as.character(a), "\\|")) %>% 
       unnest() %>% table()

#    a
# id  Ben Chris Greg Jim Steve
#  1   1     1    0   1     0
#  2   1     0    1   1     0
#  3   1     0    0   1     1

基础R中的类似物是:

df$a <- as.character(df$a)
s    <- strsplit(df$a, "|", fixed=TRUE)
table(id = rep(1:nrow(df), lengths(s)), v = unlist(s))

数据:

df = data.frame(a = c("Ben|Chris|Jim", "Ben|Greg|Jim", "Jim|Steve|Ben"))

答案 1 :(得分:6)

另一种方法是使用cSplit_e包中的splitstackshape

按列afill将数据框拆分为原始列的0和drop

library(splitstackshape)
cSplit_e(df, "a", "|", type = "character", fill = 0, drop = T)

#   a_Ben a_Chris a_Greg a_Jim a_Steve
#1     1       1      0     1       0
#2     1       0      1     1       0
#3     1       0      0     1       1

答案 2 :(得分:2)

我们可以在分割&#39; a&#39;之后使用mtabulate中的qdapTools。柱

library(qdapTools)
mtabulate(strsplit(as.character(df$a), "|", fixed = TRUE))
#  Ben Chris Greg Jim Steve
#1   1     1    0   1     0
#2   1     0    1   1     0
#3   1     0    0   1     1

答案 3 :(得分:0)

这是基础R

中的方法
# get unique set of names
myNames <- unique(unlist(strsplit(as.character(df$a), split="\\|")))
# get indicator data.frame
setNames(data.frame(lapply(myNames, function(i) as.integer(grepl(i, df$a)))), myNames)

返回

Ben Chris Jim Greg Steve
1   1     1   1    0     0
2   1     0   1    1     0
3   1     0   1    0     1

第一行使用strsplit生成在管道上拆分的名称列表&#34; |&#34;,unlistunique生成唯一名称的向量。第二行使用lapply运行这些名称,并使用grepl搜索名称,as.integer转换为二进制整数。返回的列表将转换为data.frame并使用setNames给出列名。