我正在尝试编写一些代码,这些代码将根据开始日期获取数据帧的一部分,其中每个用户的每个开始日期都不同。
假设我有以下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
有什么建议吗?提前谢谢!
答案 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