【问题标题】:getting error in [R] - missing value where TRUE/FALSE needed在 [R] 中出现错误 - 需要 TRUE/FALSE 的地方缺少值
【发布时间】:2012-10-11 20:38:34
【问题描述】:

我正在尝试遍历向量以使用 IQR 来计算范围来查找异常值。当我运行此脚本以查找 IQR 右侧的值时,我得到结果,当我向左运行时,我得到错误:缺少 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 个异常值向量,我只是得到错误而没有显示其他结果。 如何修复此脚本?非常感谢任何帮助。几天来,我一直在网上和我的书上搜索如何解决这个问题。

【问题讨论】:

  • i=16 会出错。比较后切换i&lt;-i+1
  • 您正在切换该语句的位置,以便在比较之后发生。
  • 你让i等于向量数据的长度,然后加1然后索引,因此它返回NAif语句逻辑语句失败

标签: r na


【解决方案1】:

出现错误消息是因为您让i &lt;= vectorCount 所以i 可以等于vectorCount,因此从数据中索引i = i+1 将得到NA,而if 语句将失败。

如果要根据IQR查找异常值,可以使用findInterval

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

我也将停止使用paste 创建字符消息为printed,改用message

【讨论】:

  • 谢谢,我是 R 新手,但对其他语言有一定的了解,所以我只是想通过它的细微差别找到方法。
【解决方案2】:

正如 cmets 中所述,错误是由于您构建 while 循环的方式造成的。在最后一次迭代中,i == 16 虽然只有 15 个元素需要处理。从i &lt;= vectorCount 更改为i &lt; 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 只返回那些为 TRUE 的值。您可以通过键入以下内容自行检查:

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

[ 位实际上是一个提取运算符,用于检索数据对象的子集。请参阅帮助页面了解一些好的背景?"["

【讨论】:

  • 我知道很多人认为去除异常值在统计学中是不好的做法,但在野外生物学领域,需要去除异常值才能更好地理解“大局”无论如何 - 我发现一种更简单的方法来代替 data[data outliers_right] 我发现这更有效,它还允许我将值传递给其他函数,例如直方图和绘图。 x[!x %in% boxplot.stats(x)$out]
  • @JohnP.Newbury - 很酷,直接打电话给boxplot.stats。如果您查看该函数的源代码,您会发现它基本上调用了我上面的答案。
  • @JohnP.Newbury - 同样,为了它的价值 - stackOverflow 鼓励您回答自己的问题...如果它是您认为的“最佳答案”,请接受它...cmets 可能是已删除/删除/或人们可能没有像自己阅读答案那样阅读它们。
猜你喜欢
  • 2019-02-25
  • 2013-02-24
  • 2018-08-09
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 1970-01-01
  • 2020-04-22
  • 1970-01-01
相关资源
最近更新 更多