我有一个这样的数据框:
df <- data.frame(c(1,2,3,4,5,6,7), c(0,23,55,0,1,40,21))
names(df) <- c("a", "b")
a b
1 0
2 23
3 55
4 0
5 1
6 40
7 21
现在,我想用最接近的较大值替换第b
列中小于 22 的所有值。当然可以使用循环,但由于我有相当大的数据集,这太慢了。
解决方案应如下所示:
a b
1 23
2 23
3 55
4 55
5 40
6 40
7 40
这是一个tidyverse
的可能性(但请注意@phiver对替换歧义的评论(
library(tidyverse);
df %>%
mutate(b = ifelse(b < 22, NA, b)) %>%
fill(b) %>%
fill(b, .direction = "up");
# a b
#1 1 23
#2 2 23
#3 3 55
#4 4 55
#5 5 55
#6 6 40
#7 7 40
说明:将b < 22
的值替换为NA
,然后使用fill
用上一个/后面的非NA
条目填充NA
。
示例数据
df <- data.frame(a = c(1,2,3,4,5,6,7), b = c(0,23,55,0,1,40,21))
您可以使用zoo::rollapply
:
library(zoo)
df$b <- rollapply(df$b,3,function(x)
if (x[2] < 22) min(x[x>22]) else x[2],
partial =T)
# df
# a b
# 1 1 23
# 2 2 23
# 3 3 55
# 4 4 55
# 5 5 40
# 6 6 40
# 7 7 40
在基本R
中,您可以对相同的输出执行此操作:
transform(df, b = sapply(seq_along(b),function(i)
if (b[i] < 22) {
bi <- c(b,Inf)[seq(i-1,i+1)]
min(bi[bi>=22])
} else b[i]))