2013-11-26 34 views
3

对于一组观察我有日期的响应事件。检查是否有任何值在一个范围内

structure(list(Date1_P2 = structure(c(14061, 14944, 14944), class = "Date"), 
    Date2_P2 = structure(c(NA, 11566, 11747), class = "Date"), 
    Date3_P2 = structure(c(NA, 10408, 11627), class = "Date"), 
    Date4_P2 = structure(c(NA, 8370, 11566), class = "Date")), .Names = c("Date1_P2", 
"Date2_P2", "Date3_P2", "Date4_P2"), row.names = c(NA, 3L), class = "data.frame") 
> dates 
    Date1_P2 Date2_P2 Date3_P2 Date4_P2 
1 2008-07-01  <NA>  <NA>  <NA> 
2 2010-12-01 2001-09-01 1998-07-01 1992-12-01 
3 2010-12-01 2002-03-01 2001-11-01 2001-09-01 

我想创建一个变量,TRUE如果这些日期的范围内的触发事件之内。假设,2001年9月发生了一些事情,观察结果可能已经回应或预期。我已经写下面的函数,

checkmove <- function(event, range, moves){ 
    moves <- as.numeric(moves) 
    early <- as.numeric(event - range) 
    late <- as.numeric(event + range) 
    moved <- any(moves > early & moves < late, na.rm=TRUE) 
    return(moved) 
} 

如果该事件的任一侧在180天内的响应,则值应为TRUE。该函数一行一行地工作,但我不能让它在整个表上工作。

# This is right 
> checkmove(as.Date("2001-09-01"), 180, dates[1,]) 
[1] FALSE 
> checkmove(as.Date("2001-09-01"), 180, dates[2,]) 
[1] TRUE 
> checkmove(as.Date("2001-09-01"), 180, dates[3,]) 
[1] TRUE 
# This is wrong 
> apply(dates, 1, function(x) checkmove(as.Date("2001-09-01"), 180, x)) 
    1  2  3 
FALSE FALSE FALSE 
Warning messages: 
1: In checkmove(as.Date("2001-09-01"), 180, x) : 
    NAs introduced by coercion 
2: In checkmove(as.Date("2001-09-01"), 180, x) : 
    NAs introduced by coercion 
3: In checkmove(as.Date("2001-09-01"), 180, x) : 
    NAs introduced by coercion 

我没有使用正确的apply函数吗?我真的宁愿避免for循环。有没有更好的方法可以开始呢?

回答

3

是的,apply强制类matrix中的数据帧dates。所以这些值不再是类date,而是character。因此as.numeric不“工作”(由强制引入的新手)。

> dates 
    Date1_P2 Date2_P2 Date3_P2 Date4_P2 
1 2008-07-01  <NA>  <NA>  <NA> 
2 2010-12-01 2001-09-01 1998-07-01 1992-12-01 
3 2010-12-01 2002-03-01 2001-11-01 2001-09-01 
> apply(dates, 1, function(x) class(x)) 
      1   2   3 
"character" "character" "character" 

请使用“ddply”系列试用plyr包装。例如

> library(plyr) 
> aaply(dates, 1, function(x) checkmove(as.Date("2001-09-01"), 180, x), .expand=F) 
    1  2  3 
FALSE TRUE TRUE 
+0

优秀。我觉得'base'和'plyr'应用函数之间的分裂是R中最大的障碍之一。 – gregmacfarlane

+0

@gmacfarlane plyr函数更加“用户友好”(特别是在输入/输出数据类型中提供多种选择) 。如果需要/想要“基础”解决方案,那么你有:1)for循环,2)在apply之前转换为numeric,3)转换为日期,然后返回到'apply'中的数字(这将会更慢,但仍然是有效的选项) – Michele

相关问题