2013-03-09 67 views
1

我已经更新的问题,作为一个)我阐述的问题没有明确的第一次尝试,B)我的确切需求也有所转移。选择连续的日期项

我要特别感谢Hemmo伟大的帮助迄今为止 - 和道歉不阐明我的问题显然不够给他。他的代码(解决问题的早期版本)显示在答案部分。

在一个高层次的 - 我期待的代码,有助于识别和区分不同个体的连续空闲时间的不同的块。更具体地讲 - 代码将理想:

  • 检查whehter活动被标记为“自由”
  • 检查是否连续数周(本周早些时候,一周后)的由同一人哪里还打成花费的时间“自由”。
  • 给出该人员连续几周被标记为“自由”的整个街区作为期望结果列中的指标。需要注意的是时间周期的lenght(例如,1 consec周,4 consec周,8 consec周)将变化
  • 最后 - 由于需要对这些簇的特性进一步的分析,不同的块应该接收不同的指标。 (如保罗的行军块将具有值为1时,可能会阻止值2,和金正日的块三月将拥有价值3)

希望当一个着眼于例如数据帧,这一点就更清楚(见期望的最终柱)

任何帮助非常理解的,对于每下面的测试数据帧的代码。

预先非常感谢,

W¯¯

实施例(注意,在最后一列应当由代码生成,纯粹包括作为例证):

  Week Name Activity Hours Desired_Outcome 
1 01/01/2013 Paul  Free 40    1 
2 08/01/2013 Paul  Free 10    1 
3 08/01/2013 Paul Project A 30    0 
4 15/01/2013 Paul Project B 30    0 
5 15/01/2013 Paul Project A 10    0 
6 22/01/2013 Paul  Free 40    2 
7 29/01/2013 Paul Project B 40    0 
8 05/02/2013 Paul  Free 40    3 
9 12/02/2013 Paul  Free 10    3 
10 19/02/2013 Paul  Free 30    3 
11 01/01/2013 Kim Project E 40    0 
12 08/01/2013 Kim  Free 40    4 
13 15/01/2013 Kim  Free 40    4 
14 22/01/2013 Kim Project E 40    0 
15 29/01/2013 Kim  Free 40    5 

代码数据帧:

Name=c(rep("Paul",10),rep("Kim",5)) 
Week=c("01/01/2013","08/01/2013","08/01/2013","15/01/2013","15/01/2013","22/01/2013","29/01/2013","05/02/2013","12/02/2013","19/02/2013","01/01/2013","08/01/2013","15/01/2013","22/01/2013","29/01/2013") 
Activity=c("Free","Free","Project A","Project B","Project A","Free","Project B","Free","Free","Free","Project E","Free","Free","Project E","Free") 
Hours=c(40,10,30,30,10,40,40,40,10,30,40,40,40,40,40) 
Desired_Outcome=c(1,1,0,0,0,2,0,3,3,3,0,4,4,0,5) 
df=as.data.frame(cbind(Week,Name,Activity,Hours,Desired_Outcome))   
df 
+0

目前还不清楚是什么你的输出方式。你能否详细说明一下? – flodel 2013-03-09 12:43:57

回答

2

编辑:这是杂乱的,因为这个问题已编辑好几次,所以我删除了旧的答案。

checkFree<-function(df){ 
    df$Week<-as.Date(df$Week,format="%d/%m/%Y") 
    df$outcome<-numeric(nrow(df)) 

    if(df$Activity[1]=="Free"){ #check first 
    counter<-1 
    df$outcome[1]<-counter  
    } else counter<-0 
    for(i in 2:nrow(df)){ 
    if(df$Activity[i]=="Free"){ 
     LastWeek <- (df$Week >= (df$Week[i]-7) & 
         df$Week < (df$Week[i])) 
     if(all(df$Activity[LastWeek]!="Free")) 
     counter<-counter+1 
     df$outcome[i]<-counter 
    } 
    } 
    df 
} 

splitdf<-split(df, Name) 

df<-unsplit(lapply(splitdf,checkFree),Name) 

uniqs<-unique(df2$Name) #for renumbering 
for(i in 2:length(uniqs)) 
    df$outcome[df$Name==uniqs[i] & df$outcome>0]<- 
    max(df$outcome[df$Name==uniqs[i-1]]) + 
    df$outcome[df$Name==uniqs[i] & df$outcome>0] 
    df 

这应该这样做,尽管上面的代码可能远不是最优的。

+0

Hemmo - 非常感谢。请注意,我调整了问题 - 道歉不清楚。试图玩弄/调整你先前的建议,但努力分配整个块的多个星期相同的代码。试图增加自己的功能与附加线也检查“垂直”以前想要的结果分数来确定是否需要一个新的指标,但不能使它工作 – user1885116 2013-03-12 23:37:16

+0

@ user1885116我做了一个新的功能,应该做的事情,你想。今后,我建议你提出新的问题,因为现在的结果与以前想要的完全不同,其他答案已经过时,后来很难再读到这里发生的事情。 – 2013-03-13 05:18:13

+0

谢谢hemmo(再次)。我是否应该将整件事重新发布为新问题?如果前一行不是前一周(例如,如果在给定日期有多个项目条目,并且前一周的自由条目为2或3或更多行),则新代码不覆盖的唯一内容。不幸的是,由于结构数据库,不能过滤掉。但是 - 我可以创建一个小循环来检查之前的5-10行,或使用周函数)。再次感谢-Wouter – user1885116 2013-03-13 15:50:22

1

使用user1885116到Hemmo的回答为指导,以什么希望的评论,这里是一个略微简单的方法:

N <- 1 
x <- with(df, df[Activity=='Free',]) 
y <- with(x, diff(Week)) <= N*7 

df$outcome <- 0 
df[rownames(x[c(y, FALSE) | c(FALSE, y),]),]$outcome <- 1 

df 

##   Week Activity Hours Desired_Outcome outcome 
## 1 2013-01-01 Project A 40    0  0 
## 2 2013-01-08 Project A 10    0  0 
## 3 2013-01-08  Free 30    1  1 
## 4 2013-01-15 Project B 30    0  0 
## 5 2013-01-15  Free 10    1  1 
## 6 2013-01-22 Project B 40    0  0 
## 7 2013-01-29  Free 40    0  0 
## 8 2013-02-05 Project C 40    0  0