如何用 NA 替换 data.frame 中不等于随机选择的值的列中的值?

How to replace values in a column in a data.frame not equal to randomly selected values with NAs?

我从 df data.frame 中的变量 a 中随机选择了 30 个值。

set.seed(123) 
date <- as.Date(seq(as.Date("2003-01-01"), as.Date("2003-05-31"), by = 1), format="%Y-%m-%d") 
a    <- runif(151, 0.005, 2.3) 
df   <- data.frame(date, a) 
#select 30 random samples
rans <-sample(length(df$a), 30)

我试过了,它用 NAs.

替换了 df$a 中等于 rans 的所有值
df[,2][rans] <- NA

但我想用 NAs 替换 df$a 中所有 不等于 rans 的值,所以我尝试了以下但没用

df[,2][!rans] <- NA            #didn't work           
df[,2][!rans %in% df] <- NA    #replaced all values in df$a with NAs

有什么建议吗?

你可以试试

df[-rans,2] <- NA

负值只会丢弃列表中的那些元素

用负数索引未必更好,用setdiff。我们使用 setdiff 获取那些在 'rans' 中未找到的行序列的行索引,然后将与这些行对应的第二列值分配为 NA。

df[setdiff(seq_len(nrow(df)), rans),2] <- NA

或者不用setdiff,我们用%in%得到一个公共元素的逻辑向量,然后取反(!),这样TRUE变成FALSE,FALSE变成TRUE。将与行对应的第二列值分配为 NA。

df[!(seq_len(nrow(df)) %in% rans), 2] <- NA

如果我们使用data.table,我们将'data.frame'转换为'data.table'(setDT(df)),并将'a'赋值给'NA'那些不满足条件的行(如上所述)。

library(data.table)
setDT(df)[!(1:.N %in% rans), a:= NA]

为什么 OP 的代码不起作用?

  1. 第一个选项

    df[,2][!rans] <- NA
    

    没用因为

    !rans
    #[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
    #[23] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
    

    给出所有 FALSE 值。 否定运算符 (!) 将 vector/column 中的“0”值转换为 TRUE,将所有其他值转换为 FALSE。由于 'rans' 没有任何 0 值,它们都被转换为 FALSE。因此,通过基于所有 FALSE 的逻辑索引进行分配不会将第 2 列中的任何相应值替换为 NA。

  2. 第二个选项

    df[,2][!rans %in% df] <- NA  
    

    'df' 是 data.frame,列中的值与 'rans' 中的值不匹配。所以它又会全是假的。

    rans %in% df
    #[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
    #[23] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
    

    通过否定上述内容,所有元素现在都为 TRUE,因此它对第 2 列中的所有值进行子集化,并通过将这些元素分配给 NA,我们得到一个具有完整 NA 值的列。