2015-11-02 52 views
1

我有这样计算使用特定的行限制了故障率中的R

ID <- c("ID300","ID301","ID302","ID303","ID304","ID305","ID306","ID307","ID308","ID309") 
Measurement <- c("Length","Length","Length","Length","Length","Length","Length","Length","Length","Length") 
PASSFAIL <- c("FAIL","PASS","FAIL","FAIL#Pts","PASS","PASS","PASS","PASS","PASS","FAIL") 

df1 <- data.frame(ID,Measurement,PASSFAIL) 

第一部分 我想创建计算每个ID的故障率列一个数据帧。我试图计算的方式是使用5个ID的窗口。例如

Fail Rate = (Number of Fails)/(Number of Fails + Number of Pass) 

ID300 <- (Fails of Row1 to Row5)/(Total from Row1 to Row5) = (3/5) = 0.6 

注:DF1,任何在通过失败列已经失败被认为是失败的。

还应该返回NA如果窗口大小小于5,因此我需要的输出看起来像这样

 ID Measurement PASSFAIL FR 
1 ID300  Length  FAIL 0.6 
2 ID301  Length  PASS 0.4 
3 ID302  Length  FAIL 0.4 
4 ID303  Length FAIL#Pts 0.2 
5 ID304  Length  PASS 0.0 
6 ID305  Length  PASS 0.2 
7 ID306  Length  PASS NA 
8 ID307  Length  PASS NA 
9 ID308  Length  PASS NA 
10 ID309  Length  FAIL NA 

第2部分 一旦做到这一点,我需要重新计算每一个故障率添加新的ID考虑5.同一窗口例如,我期望这个输出是

 ID Measurement PASSFAIL FR 
1 ID296  Length  PASS 0.4 
2 ID297  Length  FAIL 0.6 
3 ID298  Length  PASS 0.6 
4 ID299  Length  FAIL 0.6 
5 ID300  Length  FAIL 0.8 
6 ID301  Length  FAIL 0.6 
7 ID302  Length  PASS NA 
8 ID303  Length  FAIL NA 
9 ID304  Length FAIL#Pts NA 
10 ID305  Length  PASS NA 

我目前做这样的计算故障率,WHI ch为整个数据帧计算它。我不知道如何使用循环来计算顺序为每个ID考虑窗口大小5.

setDT(df1) 
# aggregate 
df1 <- df1[, .(FR = (sum(PASSFAIL != "PASS")/.N))] 

请提供一些输入。

+0

我建议你看看'zoo'包中的'filter'或'rollapply'。例如。 - 'filter(grepl(“FAIL”,df1 $ PASSFAIL),rep(1,5)/ 5,sides = 1)'还要注意有一个'by ='参数可以传递给'data.table'在由'by ='变量定义的组内运行函数。 – thelatemail

回答

1

我迷失在你的第2部分,但这里的第1部分使用stats::filtergrepl呼叫搜索包含"FAIL"所有的值进行排序:

df1$FR <- NA 
vals <- na.omit(filter(grepl("FAIL",df1$PASSFAIL), rep(1,5)/5, sides=1)) 
df1$FR[seq(1,length(vals))] <- vals 

df1 
#  ID Measurement PASSFAIL FR 
#1 ID300  Length  FAIL 0.6 
#2 ID301  Length  PASS 0.4 
#3 ID302  Length  FAIL 0.4 
#4 ID303  Length FAIL#Pts 0.2 
#5 ID304  Length  PASS 0.0 
#6 ID305  Length  PASS 0.2 
#7 ID306  Length  PASS NA 
#8 ID307  Length  PASS NA 
#9 ID308  Length  PASS NA 
#10 ID309  Length  FAIL NA 

或者:

rev(filter(grepl("FAIL",rev(df1$PASSFAIL)), rep(1,5)/5, sides=1)) 

如果你想要看中。

+0

thelatemail,感谢这个解决方案,但我得到一个错误,说:“Error in UseMethod(”filter_“): 没有适用的方法'filter_ '应用于类“逻辑”的对象“”我该如何摆脱它?是因为dplyr吗? – Sharath

+0

我刚刚重新启动R会话,并再次运行它,而不使用dplyr,它的工作原理类似于魅力。真棒解决方案。非常感谢。但是我可能会在代码中稍后使用dplyr?这会是一个问题吗? – Sharath

+0

我的第二部分不过是一个“移动故障率”。因为这实际上是一个时间序列数据,所以我希望这个解决方案能够计算每个添加到数据帧的新传入数据点。但我认为你的解决方案将做到这一点。我可能真的很愚蠢地问这个问题,但我会测试它并让你知道。 – Sharath

0

您可能想尝试sapply函数,我也会为了良好的订单而声明df1没有因素。

df1 <- data.frame(ID,Measurement,PASSFAIL,stringsAsFactors = FALSE) 
df1$FR <- sapply(df1$ID,FUN = function(x) { 
    if(which(df1$ID == x) > nrow(df1)-4){ 
    return(NA_real_) 
    }else{ 
    start_ID <- which(df1$ID == x) 
    end_ID <- start_ID + 4 
    return(sum(grepl("FAIL",df1[start_ID:end_ID,"PASSFAIL"]))/5) 
    } 
}) 
+0

这很好,但它只是忽略了“FAIl#”,并且只有在passfail列中的值是pass或fail?时才有效。你可以请修改它来考虑“失败#”也作为失败吗? – Sharath

+2

你怎么能这么懒惰,队友:-),只需将我的==替换为grep – pidig89