2017-10-19 64 views
4
給出的列

如何取消選擇自編函數的參數...中給出的列。 (我還需要選擇在另一點列,所以只是在-指定...列不解決我的問題。)dplyr:取消選擇由

任何soltions是apreciated,select -helpers,操縱quosures或表達式,...

# very simple example data 
test <- data.frame(a=1:3, b=1:3, c=1:3) 

# function skeleton 
testfun <- function(x, ...){ 
    y <- select(x, ...) 
    z <- select(x, -...) # does of course not work like this 
    return(list(y, z)) # just as an example 
} 

# calling the function to select different columns 
testfun(test, a) 
testfun(test, a, b) 
+1

我會使用'select_'並傳入一個字符(矢量)。 –

回答

4

這些EAS即,解決方案是選擇正列,然後比較名稱以確定要刪除哪些列,如this answer

要直接點工作,

  1. 我們將抓住他們quosures的(quos)的列表。
  2. 爲正面選擇取消並拼接點UQS
  3. c()裏面做同樣的事情,這樣我們就有了一個選擇向量。
  4. 否定該向量做負向選擇。

這是由(3)和(4)描述的轉換。

library(dplyr) 
dots <- quos(a, b) 
quos(-c(UQS(dots))) 
#> [[1]] 
#> <quosure: frame> 
#> ~-c(~a, ~b) 
#> 
#> attr(,"class") 
#> [1] "quosures" 

完整的解決方案則是在選擇助手

test <- data.frame(a = 1:3, b = 1:3, c = 1:3) 

# function skeleton 
testfun <- function(x, ...) { 
    dots <- quos(...) 
    y <- select(x, UQS(dots)) 
    z <- select(x, -c(UQS(dots))) 
    return(list(y, z)) 
} 

testfun(test, a) 
#> [[1]] 
#> a 
#> 1 1 
#> 2 2 
#> 3 3 
#> 
#> [[2]] 
#> b c 
#> 1 1 1 
#> 2 2 2 
#> 3 3 3 

testfun(test, a, b) 
#> [[1]] 
#> a b 
#> 1 1 1 
#> 2 2 2 
#> 3 3 3 
#> 
#> [[2]] 
#> c 
#> 1 1 
#> 2 2 
#> 3 3 

測試。

testfun(test, starts_with("b"), one_of("c")) 
#> [[1]] 
#> b c 
#> 1 1 1 
#> 2 2 2 
#> 3 3 3 
#> 
#> [[2]] 
#> a 
#> 1 1 
#> 2 2 
#> 3 3 
+1

看起來'c'沒有必要,'y'的行已經在OP的問題中了,所以你可以將'z'的行改爲'z < - select(x, - !!! quos( ...))' –

+0

我的不好,你需要'c'或'testfun(test,a,b)'會失敗,那麼這行會變成'z < - select(x,-c(!!! quos(。 ..)))' –

1

那該怎麼辦?

testfun <- function(x, ...){ 
    y <- select(x, ...) 
    z <- x[, !names(x) %in% names(y)] 
    return(list(y, z)) 
} 
0

你可以試試:

testfun <- function(x, y, z){ 
    y1 <- select(x, y) 
    z1 <- select(x, -one_of(z)) 
    return(list(y1, z1)) 
} 
testfun(test, "a", "b") 
[[1]] 
    a 
1 1 
2 2 
3 3 

[[2]] 
    a c 
1 1 1 
2 2 2 
3 3 3 

您也可以指定更多的變量使用c

testfun(test, c("a", "c"), c("b", "a")) 
2

您可以使用這一招用purrr::modify_at

library(purrr) 
testfun <- function(x, ...){ 
    y <- select(x, ...) 
    z <- modify_at(x,c(...),~NULL) 
    return(list(y, z)) # just as an example 
} 

testfun(test,"a") 
# [[1]] 
# a 
# 1 1 
# 2 2 
# 3 3 
# 
# [[2]] 
# b c 
# 1 1 1 
# 2 2 2 
# 3 3 3 
+0

這看起來非常好,我會試試這個,接受另一個答案,因爲當我問這個問題時,它接近我的想法,但這看起來更實用。 – snaut