我有一个data.table,我希望在某些条件下更改某些列。
tmp = data.table(id = rep(LETTERS[1:4], each = 3), flag = c(NA, NA, 4, NA, 5, 4, NA, NA, NA, 7, 5, 6))
> tmp
id flag
1: A NA
2: A NA
3: A 4
4: B NA
5: B 5
6: B 5
7: C NA
8: C NA
9: C NA
10: D 7
11: D 5
12: D 6
我想要的是如果id列中的所有值都是NA,那么我希望该值为5,如果只有一些是NA,那么我希望该值为min,如果没有NA我想要原来的价值观。
我写了一些ifelse语句来做到这一点,但我发现的是,如果标志中没有NA,并且我返回该值的标志,它将返回它看到的第一个值。
tmp[ , "flag2" := ifelse(all(is.na(flag)), 5, ifelse(any(is.na(flag)), min(flag, na.rm = TRUE), flag)), by = .(id)]
> tmp
id flag flag2
1: A NA 4
2: A NA 4
3: A 4 4
4: B NA 5
5: B 5 5
6: B 5 5
7: C NA 5
8: C NA 5
9: C NA 5
10: D 7 7
11: D 5 7
12: D 6 7
为什么这不会返回D 5的原始序列7 5 6?并且,有没有一种简单的方法来纠正这个问题?
答案 0 :(得分:1)
any(...)
返回单个逻辑值而不是逻辑向量,因此结果采用flag
的第一个元素,与:
ifelse(FALSE, 3, c(2,3))
# [1] 2
在您的情况下,您不需要向量化ifelse
,if/else
应该有效:
tmp[ , "flag2" := if(all(is.na(flag))) 5 else if(any(is.na(flag))) min(flag, na.rm = TRUE) else flag, by = .(id)]
tmp
# id flag flag2
# 1: A NA 4
# 2: A NA 4
# 3: A 4 4
# 4: B NA 4
# 5: B 5 4
# 6: B 4 4
# 7: C NA 5
# 8: C NA 5
# 9: C NA 5
#10: D 7 7
#11: D 5 5
#12: D 6 6