我有一个包含数百万行和十列的数据框。 我的代码似乎工作,但从来没有完成for循环的原因和if语句我认为。 我想用不同的方式写它,但我被卡住了。
df <- data.frame(x = 1:5,
y = c("a", "a", "b", "b", "c"),
z = sample(5))
for (i in seq_along(df$x)){
if (df$y[i] == df$y[i+1] & df$y[i] == "a"){
df$status[i] <- 1
} else {
df$status[i] <- "ok"
}
}
答案 0 :(得分:2)
实际上,您可以用矢量化ifelse
:
df$status = ifelse(df$y == df$y[-1] & df$y == 'a', 1, 'ok')
与for
循环不同,此代码会给您一个警告。但是,警告实际上是正确,也与您的代码有关:在执行df$y
时,您正在阅读df$y[i + 1]
的最后一个元素。
你可以让这个警告消失(并使代码更明确)by borrowing the lead
function from dplyr
(简化):
lead = function (x, n = 1, default = NA) {
if (n == 0)
return(x)
`attributes<-`(c(x[-seq_len(n)], rep(default, n)), attributes(x))
}
有了这个,您可以稍微重写代码并删除警告:
df$status = ifelse(df$y == lead(df$y) & df$y == 'a', 1, 'ok')
遗憾的是,这个功能似乎不存在于基础R中。