2017-10-16 127 views
1

中的R数据帧

假设在著名iris数据集选择性地移除列值,我已确定,当Sepal.Length> 5.0,还有在我的测定装置的误差。

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

作为一个例子,这样的:

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来解决这个。尽管如此,我已经让自己失望了一个/modify_at兔子洞。对优雅的任何建议将不胜感激。

谢谢!

回答

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函数引用其他列的列工作,我们需要使用.$语法作为单独参数传入阈值列。

+0

我喜欢这个配方。它干净可读 - 感谢称重! – amormachine

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 
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> 
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 
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>