我有一个像这样的数据框:
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
答案 0 :(得分:0)
这里有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))
答案 1 :(得分:0)
您可以使用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]))