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)
。
但这会导致许多问题:
- 第一个值变为 NA。我试过在滞后函数中使用 default=Data$Reversal 调用,但无济于事。
- 每个唯一 ID 的反转值应重置为 0。现在它继续跨越 ID。我使用 group_by(ID) 尝试了一个混乱的代码,但无法让它工作,因为它破坏了我之前的 ifelse 函数。
- 这仅在出现 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")
我正在处理一个数据集,该数据集有一些数据错误。号码有时会记错。这是一些玩具数据示例:
问题是 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)
。
但这会导致许多问题:
- 第一个值变为 NA。我试过在滞后函数中使用 default=Data$Reversal 调用,但无济于事。
- 每个唯一 ID 的反转值应重置为 0。现在它继续跨越 ID。我使用 group_by(ID) 尝试了一个混乱的代码,但无法让它工作,因为它破坏了我之前的 ifelse 函数。
- 这仅在出现 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")