将变量中的值设置为NA,以另一个变量为条件

时间:2016-10-12 23:55:13

标签: r dataframe na conditional-operator

如果满足另一个变量的条件,我希望删除变量中的值。例如:

df$var1[df$condvar == 0] <- NA

上面的代码运行正常,但我需要为更多变量重复此操作,因此上面的var1会更改为var2var3等。这始终基于相同的condvar,虽然一半的变量条件为df$condvar == 1。一遍又一遍地重复这一行是很麻烦的,我想知道是否有更简洁的方法来编写代码。其中一个apply函数会帮助,还是需要创建自定义函数?

作为一个可重复的例子,我希望避免下面代码的重复性:

ex <- mtcars
ex$mpg[ex$vs == 0] <- NA
ex$disp[ex$vs == 0] <- NA
ex$drat[ex$vs == 0] <- NA
ex$cyl[ex$vs == 1] <- NA
ex$hp[ex$vs == 1] <- NA
ex$wt[ex$vs == 1] <- NA
ex


                     mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4             NA   6    NA 110   NA 2.620 16.46  0  1    4    4
Mazda RX4 Wag         NA   6    NA 110   NA 2.875 17.02  0  1    4    4
Datsun 710          22.8  NA 108.0  NA 3.85    NA 18.61  1  1    4    1
Hornet 4 Drive      21.4  NA 258.0  NA 3.08    NA 19.44  1  0    3    1
Hornet Sportabout     NA   8    NA 175   NA 3.440 17.02  0  0    3    2
Valiant             18.1  NA 225.0  NA 2.76    NA 20.22  1  0    3    1
Duster 360            NA   8    NA 245   NA 3.570 15.84  0  0    3    4
etc.

如果有一行代码适用于condvar == 0的所有变量而另一行适用于condvar == 1的变量,我将非常高兴。

4 个答案:

答案 0 :(得分:5)

这是一次希望不太复杂的尝试。如果您设置要循环的std::cout << ev.front() << "\n"; ,并希望选择相应的vars进行索引,则可以执行以下操作:

values

如果你只有两个小组,你可以通过评论中提到的@HubertL和@Phil等几个作业更简单,但使用vars <- c("mpg", "disp", "cyl", "hp") values <- c(0, 0, 1, 1) ex[vars] <- Map(function(x,y) replace(x, ex$vs == y, NA), ex[vars], vals) # mpg cyl disp hp drat wt qsec vs am gear carb #Mazda RX4 NA 6 NA 110 3.90 2.620 16.46 0 1 4 4 #Mazda RX4 Wag NA 6 NA 110 3.90 2.875 17.02 0 1 4 4 #Datsun 710 22.8 NA 108.0 NA 3.85 2.320 18.61 1 1 4 1 #Hornet 4 Drive 21.4 NA 258.0 NA 3.08 3.215 19.44 1 0 3 1 #Hornet Sportabout NA 8 NA 175 3.15 3.440 17.02 0 0 3 2 #Valiant 18.1 NA 225.0 NA 2.76 3.460 20.22 1 0 3 1 # ... 可以考虑许多带有许多可能索引值的变量,没有超过3行代码。

答案 1 :(得分:4)

感谢@HubertL(欢迎发布此作为答案,我将提升)和@smci:

ex[ex$vs == 0, c("mpg", "disp", ...)] <- NA
ex[ex$vs == 1, c("cyl", "hp", ...)] <- NA

答案 2 :(得分:3)

使用新的实验case_when函数的dplyr方法将类似于:

require(dplyr)

ex <- mtcars
ex <- ex %>%
      mutate(mpg  = case_when(.$vs==0 ~ as.double(NA), TRUE ~ .$mpg)) %>%
      mutate(disp = case_when(.$vs==0 ~ as.double(NA), TRUE ~ .$disp)) %>%
      mutate(cyl  = case_when(.$vs==1 ~ as.double(NA), TRUE ~ .$cyl)) %>%
      mutate(hp   = case_when(.$vs==1 ~ as.double(NA), TRUE ~ .$hp))

注意:

使用filter()进行解决方法:

ex <- rbind(ex %>% filter(vs==0) %>% mutate(mpg=NA, disp=NA),
            ex %>% filter(vs==1) %>% mutate(cyl=NA, hp=NA) )

由于vs

上的分割而具有重新排列行的副作用

答案 3 :(得分:0)

尝试:

ifelse(df$var1 == 0, NA, df$var1)