2017-10-16 144 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>