R中的数据透视表

时间:2018-03-26 16:36:35

标签: r pivot reshape2

我有类似的日期数据框

id     weight  beginning_date   end_date     age  categ_car

22     2       1960-06-02       1960-06-02   17     A

17     4       2001-07-02                    19     B

我想要以下数据框

id     weight  beginning_date   end_date     age  categ_car

22     2       1960-06-02       1960-06-02   17     A
22     2       1961-06-02       1961-06-02   18     A
17     4       2001-07-02                    19     B
17     4       2002-07-02                    20     B
17     4       2003-07-02                    21     B
17     4       2004-07-02                    22     B

我知道我可以使用包重塑2中的融合功能来创建枢轴,但我不知道如何增加日期和年龄?

谢谢,

<磷>氮

2 个答案:

答案 0 :(得分:0)

这是帮助您前进的一些帮助。您需要从日期列获取年份,对日期列应用相同的函数,并在以下各项后绑定它们:

library(data.table)
setDT(df)
AddWeightage<-function(a,x){
  x<-cumsum(rep(1,x-1))
  return(x+a)
}
cols<-c("age")
df[,lapply(.SD,AddWeightage,x=weight), by=.(categ_car),.SDcols=cols]

以下是生成日期列的功能:

AddWeightDate<-function(a,x){
  x<-cumsum(rep(1,x-1))
  a1<-x+year(a)
  b<-substr(as.character(a),5,10)
  return(sprintf('%s%s',a1,b))
}

cols<-c('beginning_date',"end_date")
df3<-df[,lapply(.SD,AddWeightDate,x=weight), by=.(categ_car),.SDcols=cols]

答案 1 :(得分:0)

我们可以使用complete包中的filltidyr来查找解决方案。重点是使用%m+%包中的lubridate运算符生成一系列日期(递增1年)。

library(dplyr)
library(tidyr)
library(lubridate)

df %>%
  mutate(beginning_date = ymd(beginning_date), end_date = ymd(end_date)) %>%
  group_by(id) %>%
  complete(beginning_date = seq(beginning_date, beginning_date %m+% years(weight-1), 
             by="1 year")) %>%
  fill(weight, end_date, age, categ_car) %>% 
  arrange(desc(id)) %>%
  select(id, weight, beginning_date, end_date, age, categ_car)

# # A tibble: 6 x 6
# # Groups: id [2]
#      id  weight beginning_date end_date   age  categ_car
#    <int>  <int> <date>         <date>     <int> <chr>    
# 1    22      2 1960-06-02     1960-06-02    17   A        
# 2    22      2 1961-06-02     1960-06-02    17   A        
# 3    17      4 2001-07-02     NA            19   B        
# 4    17      4 2002-07-02     NA            19   B        
# 5    17      4 2003-07-02     NA            19   B        
# 6    17      4 2004-07-02     NA            19   B  

更新:根据OP的反馈,为同一个“id”处理多个begining_date

df %>%
  mutate(beginning_date = ymd(beginning_date), end_date = ymd(end_date)) %>%
  group_by(id) %>%
  complete(beginning_date = seq(as.Date(min(beginning_date), origin="1970-01-01"), 
                  as.Date(min(beginning_date), origin="1970-01-01") %m+% years(weight-1),
                                by="1 year")) %>%
  fill(weight, end_date, age, categ_car) %>% 
  arrange(desc(id)) %>%
  select(id, weight, beginning_date, end_date, age, categ_car)

数据

df <- read.table(text = 
      "id     weight  beginning_date   end_date     age  categ_car
       22     2       1960-06-02       1960-06-02   17     A
       17     4       2001-07-02         NA         19     B", 
       header = TRUE, stringsAsFactors = FALSE)

注意:已使用NA代替blank的{​​{1}}值。