2012-10-22 40 views
1

我试图通过矢量来找到使用IQR计算范围的异常值。当我运行这个脚本寻找IQR右侧的值时,我得到了结果,当我向左运行时,出现错误:缺少值,其中TRUE/FALSE所需。我怎样才能清除数据集中的真假? 这里是我的脚本:在[R]中出错 - 需要TRUE/FALSE的缺失值

data = c(100, 120, 121, 123, 125, 124, 123, 123, 123, 124, 125, 167, 180, 123, 156) 
Q3 <- quantile(data, 0.75) ##gets the third quantile from the list of vectors 
Q1 <- quantile(data, 0.25) ## gets the first quantile from the list of vectors 
outliers_left <-(Q1-1.5*IQR(data)) 
outliers_right <-(Q3+1.5*IQR(data)) 
IQR <- IQR(data) 
paste("the innner quantile range is", IQR) 
Q1 # quantil at 0.25 
Q3 # quantile at 0.75 
# show the range of numbers we have 
paste("your range is", outliers_left, "through", outliers_right, "to determine outliers") 
# count ho many vectors there are and then we will pass this value into a loop to look for 
# anything above and below the Q1-Q3 values 
vectorCount <- sum(!is.na(data)) 
i <- 1 
while(i < vectorCount){ 
i <- i + 1 
x <- data[i] 
# if(x < outliers_left) {print(x)} # uncomment this to run and test for the left 
if(x > outliers_right) {print(x)} 
} 

,我得到的错误是

[1] 167 
[1] 180 
[1] 156 
Error in if (x > outliers_right) { : 
missing value where TRUE/FALSE needed 

,你可以看到,如果您运行此脚本,它被发现在右边我的3个外行,也引发错误,但是当我在IQR的左边再次运行这个函数,并且向量中出现了100个异常值时,我只是得到错误而没有显示其他结果。 我该如何修复这个脚本?任何帮助不胜感激。我一直在网上和我的书上搜索如何解决这个问题。

+1

'i = 16'发生错误。比较后切换'i <-i + 1'。 – liuminzhao

+0

您正在切换该语句的位置,以便在比较后发生。 –

+0

是的,谢谢,修好了! –

回答

3

正如评论中指出的那样,错误是由于您构建while循环的方式。在最后一次迭代中,i == 16尽管只有15个元素需要处理。从i <= vectorCounti < vectorCount修复问题更改:

i <- 1 
while(i < vectorCount){ 
    i <- i + 1 
    x <- data[i] 
    # if(x < outliers_left) {print(x)} # uncomment this to run and test for the left 
    if(x > outliers_right) {print(x)} 
} 
#----- 
[1] 167 
[1] 180 
[1] 156 

然而,这实在是不属于R是如何工作的,你很快就会在那个代码需要多长时间为任何明显的大小的数据运行受挫。 R是“矢量化”,意思是你可以一次对data的所有15个元素进行操作。要打印的异常值,我应该这样做:

data[data > outliers_right] 
#----- 
[1] 167 180 156 

或者使用OR运算符立刻让所有的人:

data[data< outliers_left | data > outliers_right] 
#----- 
[1] 100 167 180 156 

对于一个小范围内,上述逻辑比较创建布尔data的每个元素的值和R只返回那些是真的。您可以通过键入检查自己这一点:

data > outliers_right 
#---- 
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE TRUE 

[位实际上是一种提取操作,用于检索数据对象的子集。请参阅帮助页面获取一些良好背景?"["

+0

我知道很多人认为去除异常值是统计学上不好的做法,但在野外生物学领域,需要去除异常值才能更好地理解“大图” 无论如何 - 我发现了一个更简单的方法这而不是 data [data outliers_right] 我发现这是更有效的,它还允许我将值传递到其他函数,如直方图和图。 x [!x%in boxplot.stats(x)$ out] –

+0

@ JohnP.Newbury - 很酷,很好的调用直接调用'boxplot.stats'。如果你看看这个函数的源代码,你会发现它基本上调用了我上面的答案。 – Chase

+0

@ JohnP.Newbury - 同样,它的价值 - stackOverflow鼓励您回答您自己的问题......并接受它,如果这是您的观点中的“最佳答案”......评论可能会被删除/删除/或者人们可能会只是没有像答案一样阅读它们。 – Chase

1

错误消息的出现是因为你,你让i <= vectorCount所以i可以等于vectorCount,从而从数据索引i = i+1会给NAif语句将失败。

如果你想找到基于该IQR的波动,您可以使用findInterval

outliers <- data[findInterval(data, c(Q1,Q3)) != 1] 

我也将停止使用paste创建字符的信息是printed,使用message代替。

+0

谢谢,我是R新手,但对其他语言也很熟悉通过它的细微差别找到我的方式。 –