使用tidyverse扩展数据框

时间:2017-01-04 19:02:07

标签: r dplyr tidyr tidyverse

以下是我尝试做的一个例子:

df <- data.frame(
  id = letters[1:5],
  enum_start = c(1, 1, 1, 1, 1),
  enum_end = c(1, 5, 3, 7, 2)
)

df2 <- df %>%
  split(.$id) %>%
  lapply(function(x) cbind(x, hello = seq(x$enum_start, x$enum_end, by = 1L))) %>%
  bind_rows
df2
#     id enum_start enum_end hello
# 1   a          1        1  1
# 2   b          1        5  1
# 3   b          1        5  2
# 4   b          1        5  3
# 5   b          1        5  4
# 6   b          1        5  5
# 7   c          1        3  1
# 8   c          1        3  2
# 9   c          1        3  3
# 10  d          1        7  1
# 11  d          1        7  2
# 12  d          1        7  3
# 13  d          1        7  4
# 14  d          1        7  5
# 15  d          1        7  6
# 16  d          1        7  7
# 17  e          1        2  1
# 18  e          1        2  2

请注意hello的起始值和结束值取决于数据,因此每个id的行数是动态的。我正在寻找一个可能来自tidyr expand的解决方案,但我正在努力。

2 个答案:

答案 0 :(得分:2)

这是一个dplyr / tidyr方法

group_by(df, id) %>% 
  expand(enum_start, enum_end, hello = full_seq(enum_end:enum_start, 1))

不确定是否有没有分组数据的tidyr-way(知道会很有趣)

答案 1 :(得分:0)

这是一个产生所需输出的基本R方法。

dfNew <- within(df[rep(seq_len(nrow(df)), df$enum_end), ],
                hello <- sequence(df$enum_end))

sequence将返回自然数并采用允许重复重新计数的向量。它用于制作&#34;你好&#34;变量。 within减少了输入并返回修改后的data.frame。我给它添加了df的扩展版本,其中使用rep[重复行。

dfNew
    id enum_start enum_end hello
1    a          1        1     1
2    b          1        5     1
2.1  b          1        5     2
2.2  b          1        5     3
2.3  b          1        5     4
2.4  b          1        5     5
3    c          1        3     1
3.1  c          1        3     2
3.2  c          1        3     3
4    d          1        7     1
4.1  d          1        7     2
4.2  d          1        7     3
4.3  d          1        7     4
4.4  d          1        7     5
4.5  d          1        7     6
4.6  d          1        7     7
5    e          1        2     1
5.1  e          1        2     2