【问题标题】:Remove outliers based on a preceding value根据前一个值删除异常值
【发布时间】:2017-12-06 15:25:04
【问题描述】:

如何使用一个值不能比其前一个值高 2 倍以上的标准来删除异常值。

这是我的尝试:

x<-c(1,2,6,4,10,20,50,10,2,1)

remove_outliers <- function(x, na.rm = TRUE, ...) {
  for(i in 1:length(x))
  x < (x[i-1] + 2*x)
  x
}

remove_outliers(y)

预期结果:1,2,4,10,20,2,1

谢谢!

【问题讨论】:

  • 2 倍高意味着​​什么?
  • 是的,我的意思是:x
  • 你能把公式写清楚吗? x

标签: r outliers


【解决方案1】:

我认为应该在您的数据中删除前 10 个,因为 10>2*4。这是一种无需循环即可完成所需操作的方法。我使用的是dplyr 版本的lag

library(dplyr)
x<-c(1,2,6,4,10,20,50,10,2,1)
x[c(TRUE,na.omit(x<=dplyr::lag(x)*2))]
[1]  1  2  4 20 10  2  1

编辑

要将其与data.frame 一起使用:

df <- data.frame(id=1:10, x=c(1,2,6,4,10,20,50,10,2,1))
df[c(TRUE,na.omit(df$x<=dplyr::lag(df$x,1)*2)),]

   id  x
1   1  1
2   2  2
4   4  4
6   6 20
8   8 10
9   9  2
10 10  1

【讨论】:

  • 奇怪,我试过你的代码,但结果是:[1] 1 2 6 4 10 20 50 10 2 1 NA
  • @MbrMbr @AK88 是的,我已经加载了dplyr,所以它是那个版本而不是stats。很遗憾,Hadley 为这样的重要功能选择了完全相同的名称。我也和filter有冲突。
  • @PLapointe 是的,有两个同名的函数会让人困惑。
  • 是否有一种简单的方法可以直接在数据帧上使用此解决方案,其中 x 是列 [2]
【解决方案2】:

一个简单的sapply:

bool<-sapply(seq_along(1:length(x)),function(i) {ifelse(x[i]<2*x[i-1],FALSE,TRUE)})

 bool
[[1]]
logical(0)

[[2]]
[1] TRUE

[[3]]
[1] TRUE

[[4]]
[1] FALSE

[[5]]
[1] TRUE

[[6]]
[1] TRUE

[[7]]
[1] TRUE

[[8]]
[1] FALSE

[[9]]
[1] FALSE

[[10]]
[1] FALSE

导致:

x[unlist(bool)]
[1]  1  2  4 10 20  1

【讨论】:

  • 预期结果应该是:[1] 1 2 4 20 10 2 1
猜你喜欢
  • 2023-02-18
  • 2021-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-10
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
相关资源
最近更新 更多