Dummify字符列并查找唯一值

时间:2017-02-22 09:41:20

标签: r dummy-variable

我有一个具有以下结构的数据框

test <- data.frame(col = c('a; ff; cc; rr;', 'rr; a; cc; e;'))

现在我想从中创建一个数据框,其中包含测试数据框中每个唯一值的命名列。唯一值是以';'结尾的值角色,从空间开始,不包括空间。然后对于列中的每一行,我希望用1或0填充虚拟列。如下所示

data.frame(a = c(1,1), ff = c(1,0), cc = c(1,1), rr = c(1,0), e = c(0,1))

  a ff cc rr e
1 1  1  1  1 0
2 1  0  1  1 1

我尝试使用for循环和列中的唯一值创建一个df,但它变得很乱。我有一个可用的向量,包含列的唯一值。问题是如何创建1和0。我在mutate_all()尝试了一些grep()函数,但这不起作用。

7 个答案:

答案 0 :(得分:8)

我会使用splitstackshape mtabulate来自qdapTools个套餐,将其作为一个班轮, 即。

library(splitstackshape)
library(qdapTools)

mtabulate(as.data.frame(t(cSplit(test, 'col', sep = ';', 'wide'))))
#   a cc ff rr e
#V1 1  1  1  1 0
#V2 1  1  0  1 1

它也可以是splitstackshape,因为@ A5C1D2H2I1M1N2O1R2T1在评论中提及,

cSplit_e(test, "col", ";", mode = "binary", type = "character", fill = 0)

答案 1 :(得分:6)

这是一个可能的data.table实现。首先,我们将行拆分成列,融化成一列并将其展开,同时计算每行的事件

library(data.table)
test2 <- setDT(test)[, tstrsplit(col, "; |;")]
dcast(melt(test2, measure = names(test2)), rowid(variable) ~ value, length)
#    variable a cc e ff rr
# 1:        1 1  1 0  1  1
# 2:        2 1  1 1  0  1

答案 2 :(得分:3)

我们可以使用tidyverse

执行此操作
library(tidyverse)
rownames_to_column(test, 'grp') %>%
        separate_rows(col) %>% 
        filter(col!="")  %>% 
        count( grp, col) %>%
        spread(col, n, fill = 0) %>%
        ungroup() %>% 
        select(-grp)
# A tibble: 2 × 5
#      a    cc     e    ff    rr
#* <dbl> <dbl> <dbl> <dbl> <dbl>
#1     1     1     0     1     1
#2     1     1     1     0     1

答案 3 :(得分:3)

这是基础R解决方案。首先删除空间。获得所有独特的组合。拆分实际数据框,然后在cols中检查它的存在,这将包含所有组合。然后你得到一个逻辑矩阵,可以很容易地转换成数字。

test=as.data.frame(apply(test,2,function(x)gsub('\\s+', '',x)))
cols=unique(unlist(strsplit(as.character(test$col), split = ';'))) 
yy=strsplit(as.character(test$col), split = ';') 
z=as.data.frame(do.call.rbind(lapply(yy, function(x) cols %in% x)))
names(z)=cols
z=as.data.frame(lapply(z, as.integer))

答案 4 :(得分:3)

这是一个基础R方法:

x   <- strsplit(as.character(test$col), ";\\s?") # split the strings
lvl <- unique(unlist(x))                         # get unique elements
x   <- lapply(x, factor, levels = lvl)           # convert to factor
t(sapply(x, table))                              # count elements and transpose
#     a ff cc rr e
#[1,] 1  1  1  1 0
#[2,] 1  0  1  1 1

答案 5 :(得分:3)

tidytexttidyverse

的另一种方法
library(tidyverse)
library(tidytext) #for unnest_tokens()
df <- test %>%
    unnest_tokens(word, col) %>%
    rownames_to_column(var="row") %>%
    mutate(row = floor(parse_number(row)),
           val = 1) %>%
    spread(word, val, fill = 0) %>%
    select(-row)
df
#    a cc e ff rr
#1   1  1 0  1  1
#2   1  1 1  0  1

答案 6 :(得分:1)

另一个没有任何额外包的简单解决方案:

x =  c('a; ff; cc; rr;', 'rr; a; cc; e;')
G = lapply(strsplit(x,';'), trimws)
dict = sort(unique(unlist(G)))
do.call(rbind, lapply(G, function(g) 1*sapply(dict, function(d) d %in% g)))