我可以在data.table中使用dcast进行字符串拆分吗?

时间:2019-07-20 06:22:39

标签: r

分割字符串,使用唯一值构建列,并根据字符串填充值。

示例数据表:

library(data.table)
(dt <- data.table(id = as.numeric(1:5),
                 x = c(NA, "ab.cde", "co.hij.ab", "cox.cde.kl", NA)))

广播方式:接近但不完全

dcast(dt, id ~ x, value.var = "id")
dt[dcast(dt, id ~ x, value.var = "id"), on=.(id = id)]

dcast建立了 some 列并填充了 some 值,但是它没有满足我的要求。

字符串拆分方法:我无法移调

dt[, unique(unlist(strsplit(dt$x, ".", fixed = TRUE))) :=
tstrsplit(dt$x, ".", fixed = TRUE)]

该消息说我的LHS有7列,而我的RHS只有3列,所以转置不起作用。也许我可以构建列并稍后填充值:

dt[, unique(unlist(strsplit(dt$x, ".", fixed = TRUE))) := character()]

现在我越来越近了,但仍然不在那儿。我需要根据dt $ x上的匹配项(或其他内容)用1和0填充这些列;

  • id 1在列上应为1:NA
  • id 2的列应为1:ab和cde
  • id 3的co,hij和ab列应为1
  • id 4的列应为1:cox,cde和kl
  • id 5的列应为1:NA

2 个答案:

答案 0 :(得分:0)

使用dplyrtidyr的一个选项是将"."上的字符串分割成单独的行,然后spread使其变成宽格式。

library(dplyr)
library(tidyr)

dt %>%
  mutate(x1 = x) %>%
  separate_rows(x, sep = "\\.") %>%
  mutate(temp = 1) %>%
  spread(x, temp, fill = 0)


#  id         x1 ab cde co cox hij kl <NA>
#1  1       <NA>  0   0  0   0   0  0    1
#2  2     ab.cde  1   1  0   0   0  0    0
#3  3  co.hij.ab  1   0  1   0   1  0    0
#4  4 cox.cde.kl  0   1  0   1   0  1    0
#5  5       <NA>  0   0  0   0   0  0    1

答案 1 :(得分:0)

我们可以使用data.table方法,即dcast

library(data.table)
dcast(dt[, {x1 <- strsplit(x, "\\."); c(list(unlist(x1)), 
      .SD[rep(seq_len(.N), lengths(x1))])}], id + x ~ V1, length)
#    id          x NA ab cde co cox hij kl
#1:  1       <NA>  1  0   0  0   0   0  0
#2:  2     ab.cde  0  1   1  0   0   0  0
#3:  3  co.hij.ab  0  1   0  1   0   1  0
#4:  4 cox.cde.kl  0  0   1  0   1   0  1
#5:  5       <NA>  1  0   0  0   0   0  0