有选择地删除R数据框中的列值

时间:2017-10-16 20:37:31

标签: r dplyr purrr

示例

假设在着名的iris数据集中,我已确定当Sepal.Length> 5.0,我的测量设备出错了。

在这个人为设想的示例中,我希望将Sepal.Length列保留其原始值,但如果Sepal.Length>将剩余列更改为NA。该行的5.0。

例如,这个:

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

会变成这样:

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         NA           NA          NA   NA
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         NA           1.7         NA   NA

我可以通过矢量化手动完成。有点像:

iris$Sepal.Width <- ifelse(iris$Sepal.Length > 5.0, NA, iris$Sepal.Width)

但是,在这种方法中,我需要手动指定每一列。

问题

我强烈怀疑有一种聪明的方法可以通过purrrdplyr解决这个问题。尽管如此,我还是让自己陷入pmap / modify_at兔子洞。任何对优雅的建议都会非常感激。

谢谢!

5 个答案:

答案 0 :(得分:2)

library(data.table)

dt <- copy(iris)
setDT(dt)

dt[Sepal.Length > 5.0, (which(!names(dt) == "Sepal.Length")) := NA]
#      Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#   1:          5.1          NA           NA          NA      NA
#   2:          4.9         3.0          1.4         0.2  setosa
#   3:          4.7         3.2          1.3         0.2  setosa
#   4:          4.6         3.1          1.5         0.2  setosa
#   5:          5.0         3.6          1.4         0.2  setosa
#  ---                                                          
# 146:          6.7          NA           NA          NA      NA
# 147:          6.3          NA           NA          NA      NA
# 148:          6.5          NA           NA          NA      NA
# 149:          6.2          NA           NA          NA      NA
# 150:          5.9          NA           NA          NA      NA

答案 1 :(得分:2)

替代方法是简单地使用它(如果您对所有列感兴趣,从第二个开始,这只是方便的)

iris[iris$Sepal.Length > 5.0, 2:ncol(iris)] <- NA

# And the output for first six rows

  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1          NA           NA          NA    <NA>
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4          NA           NA          NA    <NA>

答案 2 :(得分:1)

听起来这对你有用

my_clip <- function(x, z) ifelse(z>5, NA, x)
iris %>% mutate_at(vars(-Sepal.Length), my_clip, z=.$Sepal.Length)

#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1          NA           NA          NA      NA
# 2          4.9         3.0          1.4         0.2       1
# 3          4.7         3.2          1.3         0.2       1
# 4          4.6         3.1          1.5         0.2       1
# 5          5.0         3.6          1.4         0.2       1
# 6          5.4          NA           NA          NA      NA

我们使用mutate_at来抓取我们要转换的所有列,然后由于您无法在mutate_at函数中轻松引用其他列,我们需要将阈值列作为使用.$语法的单独参数。

答案 3 :(得分:0)

由于您要求提供purrr示例,此处可以使用。虽然我更喜欢已提出的data.table答案:

library(purrr)
library(tidyr)

iris %>% nest(-Sepal.Length) %>% 
mutate(data = ifelse(Sepal.Length > 5.0, 
                   map(data, function(x) x*NA), data)) %>% 
unnest

答案 4 :(得分:0)

使用magrittr,你可以这样做:

library(magrittr)
iris %>% head %>% inset(.$Sepal.Length > 5,-1,NA)

或使用基数R而不是magrittr(相同的输出,只是更丑陋的函数:),并且管道仍然需要magrittrdplyr

iris %>% head %>% `[<-`(.$Sepal.Length > 5,-1,NA)

-1是您要保留的列的索引,否定。

<强>结果

#   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# 1          5.1          NA           NA          NA    <NA>
# 2          4.9         3.0          1.4         0.2  setosa
# 3          4.7         3.2          1.3         0.2  setosa
# 4          4.6         3.1          1.5         0.2  setosa
# 5          5.0         3.6          1.4         0.2  setosa
# 6          5.4          NA           NA          NA    <NA>