我想有条件地替换data.frame中的某些值。
假设我有:
a <- c(1, 4, 5, 7, 9, 8, 3, 90)
b <- c(21, 24, 25, NA, 9, 23, NA, 3)
c <- c(214, 5, NA, NA, 59, NA, 32, 12)
d <- rep(0, 8)
test.df <- data.frame(a, b, c, d)
test.df
a b c d
1 1 21 214 0
2 4 24 5 0
3 5 25 NA 0
4 7 NA NA 0
5 9 9 59 0
6 8 23 NA 0
7 3 NA 32 0
8 90 3 12 0
我的第一个问题是为什么以下命令不会返回相同的内容?为什么第二个返回带有NA的行?第二个错误是什么?
subset(test.df, test.df$a >=4 & !is.na(test.df$b) & test.df$c > 4)
a b c d
2 4 24 5 0
5 9 9 59 0
8 90 3 12 0
test.df[test.df$a >=4 & !is.na(test.df$b) & test.df$c > 4, ]
a b c d
2 4 24 5 0
NA NA NA NA NA
5 9 9 59 0
NA.1 NA NA NA NA
8 90 3 12 0
我的第二个问题是,根据上述标准,如何使用d
替换列10
值以获取:
test.df
a b c d
1 1 21 214 0
2 4 24 5 10
3 5 25 NA 0
4 7 NA NA 0
5 9 9 59 10
6 8 23 NA 0
7 3 NA 32 0
8 90 3 12 10
谢谢!
答案 0 :(得分:3)
1)您的标准test.df$a >=4 & !is.na(test.df$b) & test.df$c > 4
会逃避:
[1] FALSE TRUE NA FALSE TRUE NA FALSE TRUE
如上所述,subset
会过滤掉标准规则为NA
的行(3和6)。另一方面,[
为这些提供了NA
行,因为不确定它们是否应包括在内(TRUE
)或排除在外(FALSE
)。< / p>
2)我会使用transform
和改进的标准:
test.df <- transform(test.df, d = ifelse(!is.na(a) &
!is.na(b) &
!is.na(c) &
a >= 4 &
c > 4, 10, d))
答案 1 :(得分:2)
如果您对data.table
感兴趣,那么您可能会对此感兴趣:
require(data.table) ## 1.9.2
setDT(test.df)[a >= 4 & !is.na(b) & c > 4, d := 10]
# a b c d
# 1: 1 21 214 0
# 2: 4 24 5 10
# 3: 5 25 NA 0
# 4: 7 NA NA 0
# 5: 9 9 59 10
# 6: 8 23 NA 0
# 7: 3 NA 32 0
# 8: 90 3 12 10
setDT
通过引用将data.frame转换为data.table。然后评估条件,并将其评估为TRUE的列d
的那些行替换为就地为10。