根据R中的变量开始日期对数据进行子集

时间:2014-09-18 20:09:07

标签: r date subset

我正在尝试编写一些代码,这些代码将根据开始日期获取数据帧的一部分,其中每个用户的每个开始日期都不同。

假设我有以下data.frames(实际上我的数据集大了几个数量级,但这足以作为样本集)

DF1:

 >   df
      name   start.date
1  Allison   2013-03-16
2   Andrew   2013-03-16
3     Carl   2013-03-16
4     Dora   2013-03-17
5   Hilary   2013-03-17
6    Louis   2013-03-18
7     Mary   2013-03-19
8   Mickey   2013-03-20

和df2:

> df2
       names X03.16.2013 X03.17.2013 X03.18.2013  X03.19.2013
2001 Allison           5           5           0           0
2002  Andrew           2           0           0           0
2003    Carl           10          8           11          10
2004    Dora           0           4           0           0
2005  Hilary           0           3           5           0
2006   Louis           0           0           8           3
2007    Mary           0           0           0           7
2008  Mickey           0           0           0           0

我将这两个数据框合并为一个名为tmp:

的数据框
>tmp

   name   start.date         X03.16.2013 X03.17.2013 X03.18.2013  X03.19.2013
    1  Allison   2013-03-16         5           5           0           0
    2   Andrew   2013-03-16         2           0           0           0
    3     Carl   2013-03-16         10          8           11          10
    4     Dora   2013-03-17         0           4           0           0
    5   Hilary   2013-03-17         0           3           5           0
    6    Louis   2013-03-18         0           0           8           3
    7     Mary   2013-03-19         0           0           0           7
    8   Mickey   2013-03-20         0           0           0           0

我还有一个转换为日期的df2列名列表:

>dts

[1] "2014-03-16" "2014-03-17" "2014-03-18" "2014-03-19" 

我认为解决此问题的一种方法是使用以下嵌套循环将df2中在每个用户的开始日期之前发生的所有零条目更改为NA:

for (i in 1:dim(tmp)[1]){
  for (j in 1:length(dts)){
    for (z in 4:dim(tmp)[2]){
    if (dts[j]< tmp$Date.of.Sign.Up[i]){
      tmp[i,z]<-NA
    } else {tmp[i,z]<-tmp[i,z]}
  }
}
}

这个循环的问题在于1.它将无限运行2.无法工作。无论开始日期如何,它都会将tmp中的所有值从tmp [,3:end]更改为零。理想情况下,我最终会得到这样的结果:

     name   start.date         X03.16.2013 X03.17.2013 X03.18.2013  X03.19.2013
  Allison   2013-03-16         5           5           0           0
   Andrew   2013-03-16         2           0           0           0
     Carl   2013-03-16         10          8           11          10
     Dora   2013-03-17         NA           4           0          0
   Hilary   2013-03-17         NA           3           5          0
    Louis   2013-03-18         NA           NA          8          3
     Mary   2013-03-19         NA           NA          NA         7
   Mickey   2013-03-20         NA           NA          NA         NA

有什么建议吗?提前谢谢!

1 个答案:

答案 0 :(得分:0)

您可以将“tmp”转换为长格式,将以前的标题转换为日期,将它们与开始日期进行比较,并在“标题日期”之后的开始日期时插入NA

library(reshape2)

# melt data from wide to long format
df3 <- melt(tmp, id.vars = c("name", "start.date"))

# convert 'variable' to class Date
df3$variable <- as.Date(df3$variable, format = "X%m.%d.%Y")

# compare start dates with 'variable dates' and insert NA
df3$value[df3$start.date > df3$variable] <- NA

# reshape back to wide
dcast(df3, name + start.date ~ variable)

#      name start.date 2013-03-16 2013-03-17 2013-03-18 2013-03-19
# 1 Allison 2013-03-16          5          5          0          0
# 2  Andrew 2013-03-16          2          0          0          0
# 3    Carl 2013-03-16         10          8         11         10
# 4    Dora 2013-03-17         NA          4          0          0
# 5  Hilary 2013-03-17         NA          3          5          0
# 6   Louis 2013-03-18         NA         NA          8          3
# 7    Mary 2013-03-19         NA         NA         NA          7
# 8  Mickey 2013-03-20         NA         NA         NA         NA

我们在“tmp”中循环“日期列名称”的另一种可能性:

dates <- names(tmp)[-c(1, 2)]

tmp[ , -c(1, 2)] <- sapply(dates, function(x){
  date <- as.Date(x, format = "X%m.%d.%Y")
  tmp[ , x][df2$start.date > date] <- NA
  tmp[ , x]
})

tmp  
#      name start.date X03.16.2013 X03.17.2013 X03.18.2013 X03.19.2013
# 1 Allison 2013-03-16           5           5           0           0
# 2  Andrew 2013-03-16           2           0           0           0
# 3    Carl 2013-03-16          10           8          11          10
# 4    Dora 2013-03-17          NA           4           0           0
# 5  Hilary 2013-03-17          NA           3           5           0
# 6   Louis 2013-03-18          NA          NA           8           3
# 7    Mary 2013-03-19          NA          NA          NA           7
# 8  Mickey 2013-03-20          NA          NA          NA          NA