基于多个现有列顺序生成列

时间:2018-03-05 08:37:15

标签: r dplyr

我有一个如下所示的数据框:

 df <- data.frame(project = c("A", "B"),
                  no_dwellings = c(150, 180),
                  first_occupancy = c(2020, 2019))

  project no_dwellings first_occupancy
1       A          150            2020
2       B          180            2019

project是一个标识住宅建筑区域的专栏,no_dwellings表示在这些区域最终建造了多少住宅,而first_occupancy是关于第一批居民何时开始的估计搬进新建的公寓。

我需要将这些信息纳入人口预测。我们得到的最好估计是每年(从first occupancy开始),60个住宅被搬入。因此,我需要按顺序生成组合来自first_occupancyno_dwellings的信息的列,以指示每年可能搬入多少住宅。由于建造的住宅数量不一定除以60,其余部分需要放入相应项目的最后一栏。

我希望我的数据框看起来像是为了进一步处理:

  project no_dwellings first_occupancy year_2019 year_2020 year_2021 year_2022
1       A          150            2020         0        60        60        30
2       B          180            2019        60        60        60         0

3 个答案:

答案 0 :(得分:5)

使用data.table - 包,您可以按如下方式处理:

library(data.table)

setDT(df)[, .(yr = first_occupancy:(first_occupancy + no_dwellings %/% 60),
              dw = c(rep(60, no_dwellings %/% 60), no_dwellings %% 60))
          , by = .(project, no_dwellings, first_occupancy)
          ][, dcast(.SD, project + no_dwellings + first_occupancy ~ paste0('year_',yr), value.var = 'dw', fill = 0)]

给出:

   project no_dwellings first_occupancy year_2019 year_2020 year_2021 year_2022
1:       A          150            2020         0        60        60        30
2:       B          180            2019        60        60        60         0

tidyverse

采用相同的逻辑
library(dplyr)
library(tidyr)

df %>% 
  group_by(project) %>% 
  do(data.frame(no_dwellings = .$no_dwellings, first_occupancy = .$first_occupancy,
                yr = paste0('year_',.$first_occupancy:(.$first_occupancy + .$no_dwellings %/% 60)),
                dw = c(rep(60, .$no_dwellings %/% 60), .$no_dwellings %% 60))) %>% 
  spread(yr, dw, fill = 0)

答案 1 :(得分:3)

生成所需内容的长数据框非常简单,我们可以使用make_pop_df。您所要做的就是在mutate调用中使用该函数,将结果数据框存储在非常方便的list columns&#39;中,这对于允许,使用{{ 1}}从列表列中取出数据帧,然后unnest以宽格式显示数据。

tidyr::spread

答案 2 :(得分:2)

使用complete函数创建所有年份然后填充数字的另一个解决方案。

library(dplyr)
library(tidyr)

df2 <- df %>%
  mutate(year = first_occupancy) %>%
  group_by(project) %>%
  complete(nesting(no_dwellings, first_occupancy), 
         year = full_seq(c(year, min(year) + unique(no_dwellings) %/% 60), period = 1)) %>%
  mutate(number = c(rep(60, unique(no_dwellings) %/% 60), unique(no_dwellings) %% 60),
         year = paste("year", year, sep = "_")) %>%
  spread(year, number, fill = 0) %>%
  ungroup()
df2
# # A tibble: 2 x 7
#   project no_dwellings first_occupancy year_2019 year_2020 year_2021 year_2022
#   <fct>          <dbl>           <dbl>     <dbl>     <dbl>     <dbl>     <dbl>
# 1 A               150.           2020.        0.       60.       60.       30.
# 2 B               180.           2019.       60.       60.       60.        0.