通过干预性观察扩展数据框架

时间:2018-05-16 18:12:15

标签: r dataframe dplyr

我正在尝试扩展R中的数据框,缺少明显的观察结果。这就是我的意思:

data.frame(id = c("a","b"),start = c(2002,2004), end = c(2005,2007))

这是:

 id start  end
1  a  2002 2005
2  b  2004 2007

我想要的是一个新的数据框,总共有8个观测值,其中4个用于" a"和" b",和一年是开始和结束(包括)之间的值之一。所以:

id year
a 2002
a 2003
a 2004
a 2005
b 2004
b 2005
b 2006
b 2007

据我所知,各种版本的扩展仅适用于唯一值,但此处我的数据框并未具有所有唯一值(显式)。

我想要逐步遍历每一行,然后使用sapply()生成一个数据框,然后将所有新数据框连接在一起。但这次尝试失败了:

sapply(test,function(x) { data.frame( id=rep(id,x[["end"]]-x[["start"]]), year = x[["start"]]:x[["end"]] )})

我知道必须有一些dplyr或其他魔法来解决这个问题!

3 个答案:

答案 0 :(得分:3)

您可以使用tidyrdplyr

library(tidyr)
library(dplyr)

df %>% 
  gather(key = key, value = year, -id) %>% 
  select(-key) %>% 
  group_by(id) %>%
  complete(year = full_seq(year,1))

# A tibble: 8 x 2
# Groups:   id [2]
  id     year
  <fct> <dbl>
1 a      2002
2 a      2003
3 a      2004
4 a      2005
5 b      2004
6 b      2005
7 b      2006
8 b      2007

答案 1 :(得分:2)

使用dplyrtidyr,我创建了一个包含年份列表的新列,然后删除了数据帧。

library(tidyr)
library(dplyr)

df <-
  data.frame(
    id = c("a", "b"),
    start = c(2002, 2004),
    end = c(2005, 2007)
  )


df %>% 
  rowwise() %>% 
  mutate(year = list(seq(start, end))) %>% 
  select(-start, -end) %>% 
  unnest()

输出

# A tibble: 8 x 2
  id      year
  <fct>  <int>
1 a       2002
2 a       2003
3 a       2004
4 a       2005
5 b       2004
6 b       2005
7 b       2006
8 b       2007

答案 2 :(得分:2)

使用data.table的简单解决方案:

library(data.table)

# option 1
setDT(df)[, .(year = seq(start, end)), by = id]

# option 2
setDT(df)[, .(year = start:end), by = id]

给出:

   id year
1:  a 2002
2:  a 2003
3:  a 2004
4:  a 2005
5:  b 2004
6:  b 2005
7:  b 2006
8:  b 2007

基础R的方法:

lst <- Map(seq, df$start, df$end)

data.frame(id = rep(df$id, lengths(lst)), year = unlist(lst))