【问题标题】:Is there a way to create dummy variables for years that fall between two time points?有没有办法为两个时间点之间的年份创建虚拟变量?
【发布时间】:2019-08-13 21:22:31
【问题描述】:

我正在处理一些时间序列数据,其中每一行都是对一个人的观察,我有两个时间段,开始日期和结束日期。我正在尝试为每一年创建虚拟变量,这样如果年份介于开始日期和结束日期之间,则虚拟变量被编码为 1。

最终结果是按年份将其用于人口统计数据的可视化目的。

我查看了一些软件包,但它似乎从已经提供的变量中创建了虚拟变量。由于其中一列可能缺少某些年份,因此我正在尝试寻找替代选项。

id <- c(1:3)
start.date <- c(1990, 1850, 1910)
end.date <- c(2014, 1920, 1980)

df <- data.frame(id, start.date, end.date)

df

从数据结构中可以看出,例如,我希望个体 1 将 1990 年至 2014 年之间的虚拟变量编码为 1,否则为 0。

【问题讨论】:

  • 你能从你的真实数据中提供一个样本吗?
  • 上面的dataframe是从实际数据中提取出来的。
  • 在实际数据中,您需要有一些不同的日期列。我在这里看不到。所以我不知道你的时间序列的起点。
  • 时间序列的起点是最早的 start.date(本例中为 1850)。
  • 我认为是面板数据集而不是时间序列数据。因为您也有单独的列。所以你有每个人从 1850 年到 2014 年的观察结果?这使它的长度为 165 * unique(id),对吗?

标签: r dummy-variable


【解决方案1】:

使用tidyr::expand 而不是dplyr::transmute 的另一种方法。

df1 <- data.frame(id = c(1:3),
                  start.date = c(1990, 1850, 1910),
                  end.date = c(2014, 1920, 1980))
library(dplyr)
library(tidyr)
df1 %>%
  group_by(id) %>% 
  expand(year = start.date:end.date) %>% 
  mutate(value = 1, year = paste0("Y",year)) %>% 
  ungroup %>% 
  spread(year, value, fill = 0)

#> # A tibble: 3 x 157
#>      id Y1850 Y1851 Y1852 Y1853 Y1854 Y1855 Y1856 Y1857 Y1858 Y1859 Y1860
#>   <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1     1     0     0     0     0     0     0     0     0     0     0     0
#> 2     2     1     1     1     1     1     1     1     1     1     1     1
#> 3     3     0     0     0     0     0     0     0     0     0     0     0
#> # ... with 145 more variables: Y1861 <dbl>, Y1862 <dbl>, Y1863 <dbl>,...

【讨论】:

    【解决方案2】:

    如果我理解正确,您希望每个 id 都有一个包含所有年份的数据框 -

    library(dplyr)
    library(tidyr)
    
    df %>% 
      group_by(id) %>% 
      transmute(years = list(paste0("Y", start.date:end.date)), value = 1) %>% 
      unnest() %>% 
      ungroup() %>% 
      spread(years, value, fill = 0)
    
    # showing first 10 of total 157 columns
    # A tibble: 3 x 10
         id Y1850 Y1851 Y1852 Y1853 Y1854 Y1855 Y1856 Y1857 Y1858
      <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    1     1     0     0     0     0     0     0     0     0     0
    2     2     1     1     1     1     1     1     1     1     1
    3     3     0     0     0     0     0     0     0     0     0
    

    【讨论】:

    • 这基本上是正确的,除了我想要宽格式,列名是年份(类似于exist_1850,然后是1或0。还有一些其他变量(我没有) t 包括为了便于直觉),如果可能的话,我宁愿不重塑。
    • 这是一个后续问题,完全是左字段,但我想我不妨问一下。所以这个扩展的全部目的是开始按年可视化数据。例如,使用 ggplot2 中的图查看每年的女性百分比。由于每一行都是一个观察,这是实现最终目标的最佳方式吗?我在想,如果我在 Y1850==1 (例如)时以某种方式过滤观察结果,我就可以找到 % female 然后绘图。但显然我有好几年了。
    【解决方案3】:

    这是一个基本的方法:

    seqs <- df$end.date - df$start.date+1
    
    table(data.frame(id = rep(df[['id']], seqs)
               , Y = paste0('Y', rep(df[['start.date']], seqs) + sequence(seqs) - 1)))
    
       Y
    id  Y1850 Y1851 Y1852 Y1853 Y1854 Y1855 Y1856 Y1857 Y1858 Y1859 ... lots of columns
      1     0     0     0     0     0     0     0     0     0     0
      2     1     1     1     1     1     1     1     1     1     1
      3     0     0     0     0     0     0     0     0     0     0
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-29
      • 1970-01-01
      相关资源
      最近更新 更多