【问题标题】:Replace a cell with NA according to value in another cell in R根据R中另一个单元格中的值用NA替换一个单元格
【发布时间】:2019-05-16 14:53:13
【问题描述】:

我有一个数据集,我从中制作了一个可重现的示例:

set.seed(1)
Data <- data.frame(
A = sample(0:5),
B = sample(0:5),
C = sample(0:5),
D = sample(0:5),
corr_A.B = sample(0:5),
corr_A.C = sample(0:5),
corr_A.D = sample(0:5))

> Data
  A B C D corr_A.B corr_A.C corr_A.D
1 1 5 4 2        1        2        4
2 5 3 1 3        5        5        0
3 2 2 3 4        0        1        2
4 3 0 5 0        4        0        1
5 0 4 2 1        2        3        3
6 4 1 0 5        3        4        5

我想检查,对于每一列 B、C 和 D,如果它们的一个单元格等于 0,我想在同一行上用 NA 替换相应的 corr_A 列。例如,由于 Data$B[4] 等于 0,我希望将 Data$corr_A.B[4] 替换为 NA。

我希望得到以下结果:

> Data
  A B C D corr_A.B corr_A.C corr_A.D
1 1 5 4 2        1        2        4
2 5 3 1 3        5        5        0
3 2 2 3 4        0        1        2
4 3 0 5 0        NA       0       NA
5 0 4 2 1        2        3        3
6 4 1 0 5        3        NA       5

我尝试了不同的方法,使用 for 循环,但我很挣扎。此外,在我正在处理的数据集中,还有许多其他列不需要检查该条件,我希望能够专门指定我在哪些列中查找 0 值。

如果有人愿意尝试一下?非常感谢

【问题讨论】:

    标签: r dataframe replace na


    【解决方案1】:

    一个使用函数is.na&lt;-的单行代码。

    is.na(Data[5:7]) <- Data[2:4] == 0
    
    Data
    #  A B C D corr_A.B corr_A.C corr_A.D
    #1 1 5 4 2        1        2        4
    #2 5 3 1 3        5        5        0
    #3 2 2 3 4        0        1        2
    #4 3 0 5 0       NA        0       NA
    #5 0 4 2 1        2        3        3
    #6 4 1 0 5        3       NA        5
    

    【讨论】:

    • 很好的答案。肯定比我的好。等效于Data[5:7][Data[2:4]==0]&lt;-NA
    【解决方案2】:

    对于基本 R 解决方案,我们可以在这里使用 ifelse

    Data$corr_A.B <- ifelse(Data$B == 0, NA, Data$corr_A.B)
    Data$corr_A.C <- ifelse(Data$C == 0, NA, Data$corr_A.C)
    Data$corr_A.D <- ifelse(Data$D == 0, NA, Data$corr_A.D)
    

    【讨论】:

    • 我认为应该是:Data$corr_A.B &lt;- ifelse(Data$B == 0, NA, Data$corr_A.B) Data$corr_A.C &lt;- ifelse(Data$C == 0, NA, Data$corr_A.C) Data$corr_A.D &lt;- ifelse(Data$D == 0, NA, Data$corr_A.D),因为$B$C$D 中的值并不总是与右侧三行中的值相同
    【解决方案3】:
    df<- data.frame(A=c(1,5,2,3,0,4),
                    B=c(5,3,2,0,4,1),
                    C=c(4,1,3,5,2,0),
                    D=c(2,3,4,0,1,5),
                    corr_A.B=c(1,5,0,4,2,3),
                    corr_A.C=c(2,5,1,0,3,4),
                    corr_A.D=c(4,0,2,1,3,5))
    
    df %>% mutate(corr_A.B=case_when(B==0 ~ NA_real_,
                                     TRUE~ corr_A.B),
                  corr_A.C=case_when(C==0 ~NA_real_,
                                      TRUE ~ corr_A.C),
                  corr_A.D=case_when(D==0 ~ NA_real_,
                                      TRUE ~ corr_A.D))
    A B C D corr_A.B corr_A.C corr_A.D
    1 1 5 4 2        1        2        4
    2 5 3 1 3        5        5        0
    3 2 2 3 4        0        1        2
    4 3 0 5 0       NA        0       NA
    5 0 4 2 1        2        3        3
    6 4 1 0 5        3       NA        5
    

    【讨论】:

      【解决方案4】:

      基本、单线、矢量化但复杂的解决方案:

      Data[t(t(which(Data[,2:4]==0,arr.ind=TRUE))+c(0,4))]<-NA
      

      【讨论】:

        【解决方案5】:

        使用apply()。你可以这样做:

        cbind(Data,apply(Data[c("B","C","D")],2,function(x){
          ifelse(x==0,NA,x)
        }))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-10-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-12-27
          • 1970-01-01
          相关资源
          最近更新 更多