R条件替换为'['且没有子集()

时间:2014-04-27 23:47:50

标签: r replace dataframe subset

我想有条件地替换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

谢谢!

2 个答案:

答案 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。