ifelse 替换值,如果它低于以前的值

ifelse replace value if it is lower than previous

我正在处理一个数据集,该数据集有一些数据错误。号码有时会记错。这是一些玩具数据示例:

问题是 Reversal 列应该只向上计数(每个唯一 ID)。所以在0,0,0,1,1,1,0,1,2,2,0,0,2,3的向量中,1和2后面的0不应该是0。相反,它们应该等于之前出现的任何值。我试图通过使用 dplyr 包中的 lag 函数来解决这个问题:

Data$Reversal <- ifelse(Data$Reversal < lag(Data$Reversal), lag(Data$Reversal), Data$Reversal) 。 但这会导致许多问题:

  1. 第一个值变为 NA。我试过在滞后函数中使用 default=Data$Reversal 调用,但无济于事。
  2. 每个唯一 ID 的反转值应重置为 0。现在它继续跨越 ID。我使用 group_by(ID) 尝试了一个混乱的代码,但无法让它工作,因为它破坏了我之前的 ifelse 函数。
  3. 这仅在出现 1 个错误时有效。但是,如果连续出现两个错误,它只会修复 1 个值。

或者,我发现 this 线程,其中 Andrie 提供的答案似乎也很有希望。这修复了问题 1 和 3,但我无法让此代码按 ID 工作(使用 group_by 函数)。

安德烈的回答:


local({
  r <- rle(data)
  x <- r$values
  x0 <- which(x==0) # index positions of zeroes
  xt <- x[x0-1]==x[x0+1] # zeroes surrounded by same value
  r$values[x0[xt]] <- x[x0[xt]-1] # substitute with surrounding value
  inverse.rle(r)
})

如有任何帮助,我们将不胜感激。

我认为 cummax 正是您所需要的。

基础 R

dat$Reversal <- ave(dat$Reversal, dat$ID, FUN = cummax)
dat
#    ID Owner Reversal Success
# 1   1     A        0       0
# 2   1     A        0       0
# 3   1     A        0       0
# 4   1     B        1       1
# 5   1     B        1       0
# 6   1     B        1       0
# 7   1 error        1       0
# 8   1 error        1       0
# 9   1     B        1       0
# 10  1     B        1       0
# 11  1     C        1       1
# 12  1     C        2       0
# 13  1 error        2       0
# 14  1     C        2       0
# 15  1     C        3       1
# 16  2     J        0       0
# 17  2     J        0       0

dplyr

dat %>%
  group_by(ID) %>%
  mutate(Reversal = cummax(Reversal)) %>%
  ungroup()

data.table

as.data.table(dat)[, Reversal := cummax(Reversal), by = .(ID)][]

数据,由 https://extracttable.com/

提供
dat <- read.table(header = TRUE, text = "
ID  Owner   Reversal    Success
1   A   0   0
1   A   0   0
1   A   0   0
1   B   1   1
1   B   1   0
1   B   1   0
1   error   0   0
1   error   0   0
1   B   1   0
1   B   1   0
1   C   1   1
1   C   2   0
1   error   0   0
1   C   2   0
1   C   3   1
2   J   0   0
2   J   0   0")