我有一个变量,我想忽略它的微小变化,直到阈值5,因为我将它们解释为测量误差或噪声.

我的最小数据是:

mydf = data.frame(time = 1:14,
                  variable=c(1,1,1,4,1,1,1,7,6,5,5,4,5,25))

我try 使用以下方法来消除这些小变化:

mydf %>%
  mutate(previous = lag(variable, n = 1, default = first(variable)),
         mytry = ifelse(abs(previous - variable) < 5, previous, variable)) 

   time variable previous   mytry 
1     1        1        1       1
2     2        1        1       1
3     3        1        1       1
4     4        4        1       1  <- from time 3 to 4 a small change happened
5     5        1        4       4  <- this should also be 1
6     6        1        1       1
7     7        1        1       1
8     8        7        1       7  <- initial big change
9     9        6        7       7  <- first small change ignored
10   10        5        6       6  <- second small change comes back in
11   11        5        5       5
12   12        4        5       5
13   13        5        4       4
14   14       25        5      25

从上面的解决方案中,我可以正确地识别第一个小更改并忽略它.但如果之后出现第二个小变化,它仍然在我的平滑变量中.我如何才能防止这种情况发生?我认为最好将任何较大的更改设置为新的基本值,并与此相比较,忽略小的更改.最小数据应如下所示:

   time variable previous   mytry optimal5
1     1        1        1       1         1
2     2        1        1       1         1
3     3        1        1       1         1
4     4        4        1       1         1 
5     5        1        4       4         1  
6     6        1        1       1         1
7     7        1        1       1         1
8     8        7        1       7         7 
9     9        6        7       7         7 
10   10        5        6       6         7 
11   11        5        5       5         7
12   12        4        5       5         7
13   13        5        4       4         7
14   14       25        5      25         25

下面的可视化显示了最初的小更改如何被忽略.

enter image description here

推荐答案

如果你的情况仅仅基于差值小于5,那么我们需要做reduction.这不能在矢量化操作中完成,因为行的值依赖于先前的值,该值可能会更新.

试试这个:

fun <- function(prev, this) if (abs(this-prev) < 5) prev else this
mydf %>%
  mutate(
    smoothed = Reduce(fun, variable, accumulate = TRUE)
  )
#    time variable smoothed
# 1     1        1        1
# 2     2        1        1
# 3     3        1        1
# 4     4        4        1
# 5     5        1        1
# 6     6        1        1
# 7     7        1        1
# 8     8        7        7
# 9     9        6        7
# 10   10        5        7
# 11   11        5        7
# 12   12        4        7
# 13   13        5        7
# 14   14       25       25

我使用了一个named-function来进行演示,但它可以很好地使用内联匿名函数(在这个答案的第一次编辑中出现).

如果我们将调用从Reduce(..)展开到fun,它看起来像这样:

fun(1, 1) -> 1
fun(1, 1) -> 1
fun(1, 4) -> 1
fun(1, 1) -> 1
fun(1, 1) -> 1
fun(1, 1) -> 1
fun(1, 7) -> 7
fun(7, 6) -> 7
...

Reduce的默认操作是只返回最后一个值;加上accumulate=TRUE还会提供所有中间值.

R相关问答推荐

如何使用shinyChatR包配置聊天机器人

无法将传奇添加到cowplot多情节中

如何计算前一行的值,直到达到标准?

多重RHS固定估计

警告:lmdif:info = 0. nls. lm()函数的输入参数不正确

bslib::card_header中的shine::downloadButton,图标而不是文本

提取具有连续零值的行,如果它们前面有R中的有效值

在df中保留原始变量和新变量

如何在所有绘图中保持条件值的 colored颜色 相同?

R:从geom_ol()中删除轮廓并导出为pdf

如何通过匹配R中所有可能的组合来从宽到长旋转多个列?

当每个变量值只能 Select 一次时,如何从数据框中 Select 两个变量的组合?

根据r中另一个文本列中给定的范围对各列求和

`-`是否也用于数据帧,有时使用引用调用?

Rmarkdown::Render vs Source()

根据r中每行中的日期序列,使用列名序列创建新列

Broom.Mixed::Augment不适用于Sample::分析

从data.table列表中提取特定组值,并在R中作为向量返回

如何在R曲线图弹出窗口中更改r和theta标签

向数据添加标签