使用data.table扩展数据

时间:2019-03-29 16:34:58

标签: r data.table

我有此数据。表

library(data.table)

data.table(
  id = c(rep(1, 3), rep(2, 2)),
  begin = c(1, 4, 8, 1, 11),
  end = c(3, 7, 12, 10, 12),
  state = c("A", "B", "A", "B", "A")
)

我想要这个输出:

data.table(
  id = c(1, 2),
  m1 = c("A", "B"),
  m2 = c("A", "B"),
  m3 = c("A", "B"),
  m4 = c("B", "B"),
  m5 = c("B", "B"),
  m6 = c("B", "B"),
  m7 = c("B", "B"),
  m8 = c("A", "B"),
  m9 = c("A", "B"),
  m10 = c("A", "B"),
  m11 = c("A", "A"),
  m12 = c("A", "A")
)

曾经进行序列分析的人可能已经认识到我正在尝试做seqformat包中的TRaMiNeR,但是由于使用{{1} }

3 个答案:

答案 0 :(得分:5)

使用data.table的一个选项是在创建序列列后melt设置数据集,然后按'i1','id','state'分组,得到seq uence firstlast的“值”,dcast从“长”到“宽”

dt1 <- melt(dt[, i1 := seq_len(.N)], id.vars = c("i1", "id", "state"))[,
      paste0("m", seq(first(value), last(value))), .(i1, id, state)]
dcast(dt1, id ~ V1, value.var = "state")[]
#    id m1 m10 m11 m12 m2 m3 m4 m5 m6 m7 m8 m9
#1:  1  A   A   A   A  A  A  B  B  B  B  A  A
#2:  2  B   B   A   A  B  B  B  B  B  B  B  B

答案 1 :(得分:2)

使用tidyverse的解决方案。

library(tidyverse)
library(data.table)

dat <- data.table(
  id = c(rep(1, 3), rep(2, 2)),
  begin = c(1, 4, 8, 1, 11),
  end = c(3, 7, 12, 10, 12),
  state = c("A", "B", "A", "B", "A")
)

dat2 <- dat %>%
  mutate(Index = map2(begin, end, `:`)) %>%
  unnest() %>%
  mutate(Index = str_c("m", Index)) %>%
  select(id, state, Index) %>%
  spread(Index, state) %>%
  select(id, str_c("m", 1:(ncol(.) - 1)))
dat2
#   id m1 m2 m3 m4 m5 m6 m7 m8 m9 m10 m11 m12
# 1  1  A  A  A  B  B  B  B  A  A   A   A   A
# 2  2  B  B  B  B  B  B  B  B  B   B   A   A  

答案 2 :(得分:1)

替代解决方案:

dt[, unlist(Map(`:`, begin, end)), by = .(id, state)
   ][, dcast(.SD, id ~ sprintf("m%02d", V1), value.var = "state")]

给出:

   id m01 m02 m03 m04 m05 m06 m07 m08 m09 m10 m11 m12
1:  1   A   A   A   B   B   B   B   A   A   A   A   A
2:  2   B   B   B   B   B   B   B   B   B   B   A   A

将数据保留为长格式可能更好。在以后的数据处理/分析中,长格式通常更易于在R中使用。

您可以通过以下方式实现这一目标:

dt[, unlist(Map(`:`, begin, end)), by = .(id, state)][order(id, V1)]

给出:

    id state V1
 1:  1     A  1
 2:  1     A  2
 3:  1     A  3
 4:  1     B  4
 5:  1     B  5
 6:  1     B  6
 7:  1     B  7
 8:  1     A  8
 9:  1     A  9
10:  1     A 10
11:  1     A 11
12:  1     A 12
13:  2     B  1
14:  2     B  2
15:  2     B  3
16:  2     B  4
17:  2     B  5
18:  2     B  6
19:  2     B  7
20:  2     B  8
21:  2     B  9
22:  2     B 10
23:  2     A 11
24:  2     A 12

(不需要[order(id, V1)]部分)


使用的数据:

dt <- data.table(
  id = c(rep(1, 3), rep(2, 2)),
  begin = c(1, 4, 8, 1, 11),
  end = c(3, 7, 12, 10, 12),
  state = c("A", "B", "A", "B", "A")
)