问题
Trying to exclude
- multiple columns in a call to
tidyr::gather()
- which are served as inputs to my function via a character vector argument (output of
shiny::selectInput
) instead of via...
- in a programmatic way
How would I do that with tidy eval functionality?
Since I pass multiple column names via a single function argument, I thought I needed to use !!!
(unquote-splicing) instead of !!
as layed out in Programming with dplyr. But that doesn't seem to play nicely with tidyselect::vars_select()
and it seems that the -
is causing the trouble.
This is the basic thing I'd like to do:
library(magrittr)
gather_data_1 <- function(dat, ...) {
dat %>% tidyr::gather("key", "value", ...)
}
mtcars %>% gather_data_1(-mpg, -cyl) %>% head()
#> mpg cyl key value
#> 1 21.0 6 disp 160
#> 2 21.0 6 disp 160
#> 3 22.8 4 disp 108
#> 4 21.4 6 disp 258
#> 5 18.7 8 disp 360
#> 6 18.1 6 disp 225
But I would like to pass the column names via a single argument (as in the shiny app it will be served via input$<select_input_id>
as well):
gather_data_2 <- function(dat, exclude) {
exclude <- rlang::syms(exclude)
dat %>% tidyr::gather("key", "value", -!!!exclude)
}
mtcars %>% gather_data_2(exclude = c("mpg", "cyl"))
#> Error: Can't use `!!!` at top level
Then I tried to see if -
is the problem:
gather_data_3 <- function(dat, exclude) {
exclude <- rlang::syms(exclude)
dat %>% tidyr::gather("key", "value", !!!exclude)
}
mtcars %>% gather_data_3(exclude = c("mpg", "cyl")) %>% head()
#> disp hp drat wt qsec vs am gear carb key value
#> 1 160 110 3.90 2.620 16.46 0 1 4 4 mpg 21.0
#> 2 160 110 3.90 2.875 17.02 0 1 4 4 mpg 21.0
#> 3 108 93 3.85 2.320 18.61 1 1 4 1 mpg 22.8
#> 4 258 110 3.08 3.215 19.44 1 0 3 1 mpg 21.4
#> 5 360 175 3.15 3.440 17.02 0 0 3 2 mpg 18.7
#> 6 225 105 2.76 3.460 20.22 1 0 3 1 mpg 18.1
That seems to work.
Then I tried to get the -
into the actual symbol names, but that doesn't work (at least the way I tried it ;-)):
gather_data_4 <- function(dat, exclude) {
exclude <- rlang::syms(sprintf("-%s", exclude))
dat %>% tidyr::gather("key", "value", !!!exclude)
}
mtcars %>% gather_data_4(exclude = c("mpg", "cyl"))
#> Error in .f(.x[[i]], ...): object '-mpg' not found
[1]: https://dplyr.tidyverse.org/articles/programming.html#unquote-splicing
EDIT
With the help from Lionel I was able to piece it together:
gather_data_6 <- function(dat, exclude) {
dat %>% tidyr::gather("key", "value", -c(rlang::UQS(exclude)))
}
mtcars %>% gather_data_6(exclude = c("mpg", "cyl")) %>% head()
#> mpg cyl key value
#> 1 21.0 6 disp 160
#> 2 21.0 6 disp 160
#> 3 22.8 4 disp 108
#> 4 21.4 6 disp 258
#> 5 18.7 8 disp 360
#> 6 18.1 6 disp 225
Even simplified:
gather_data_7 <- function(dat, exclude) {
dat %>% tidyr::gather("key", "value", -c(!!!exclude))
}
mtcars %>% gather_data_7(exclude = c("mpg", "cyl")) %>% head()
#> mpg cyl key value
#> 1 21.0 6 disp 160
#> 2 21.0 6 disp 160
#> 3 22.8 4 disp 108
#> 4 21.4 6 disp 258
#> 5 18.7 8 disp 360
#> 6 18.1 6 disp 225
Created on 2018-04-26 by the reprex package (v0.2.0).
回答1:
You need to unquote splice a list of expressions, not a list of symbols. For example:
library(tidyverse)
gather_data_4 <- function(.data, exclude) {
exclude <- map(syms(exclude), function(s) expr(-!!s))
gather(.data, "key", "value", !!!exclude)
}
mtcars %>% gather_data_4(exclude = c("mpg", "cyl"))
#> mpg cyl key value
#> 1 21.0 6 disp 160.000
#> 2 21.0 6 disp 160.000
#> 3 22.8 4 disp 108.000
#> 4 21.4 6 disp 258.000
#> 5 18.7 8 disp 360.000
#> 6 18.1 6 disp 225.000
#> 7 14.3 8 disp 360.000
#> 8 24.4 4 disp 146.700
#> 9 22.8 4 disp 140.800
#> 10 19.2 6 disp 167.600
#> 11 17.8 6 disp 167.600
#> 12 16.4 8 disp 275.800
#> 13 17.3 8 disp 275.800
#> 14 15.2 8 disp 275.800
#> 15 10.4 8 disp 472.000
#> 16 10.4 8 disp 460.000
#> 17 14.7 8 disp 440.000
#> 18 32.4 4 disp 78.700
#> 19 30.4 4 disp 75.700
#> 20 33.9 4 disp 71.100
#> 21 21.5 4 disp 120.100
#> 22 15.5 8 disp 318.000
#> 23 15.2 8 disp 304.000
#> 24 13.3 8 disp 350.000
#> 25 19.2 8 disp 400.000
#> 26 27.3 4 disp 79.000
#> 27 26.0 4 disp 120.300
#> 28 30.4 4 disp 95.100
#> 29 15.8 8 disp 351.000
#> 30 19.7 6 disp 145.000
#> 31 15.0 8 disp 301.000
#> 32 21.4 4 disp 121.000
#> 33 21.0 6 hp 110.000
#> 34 21.0 6 hp 110.000
#> 35 22.8 4 hp 93.000
#> 36 21.4 6 hp 110.000
#> 37 18.7 8 hp 175.000
#> 38 18.1 6 hp 105.000
#> 39 14.3 8 hp 245.000
#> 40 24.4 4 hp 62.000
#> 41 22.8 4 hp 95.000
#> 42 19.2 6 hp 123.000
#> 43 17.8 6 hp 123.000
#> 44 16.4 8 hp 180.000
#> 45 17.3 8 hp 180.000
#> 46 15.2 8 hp 180.000
#> 47 10.4 8 hp 205.000
#> 48 10.4 8 hp 215.000
#> 49 14.7 8 hp 230.000
#> 50 32.4 4 hp 66.000
#> 51 30.4 4 hp 52.000
#> 52 33.9 4 hp 65.000
#> 53 21.5 4 hp 97.000
#> 54 15.5 8 hp 150.000
#> 55 15.2 8 hp 150.000
#> 56 13.3 8 hp 245.000
#> 57 19.2 8 hp 175.000
#> 58 27.3 4 hp 66.000
#> 59 26.0 4 hp 91.000
#> 60 30.4 4 hp 113.000
#> 61 15.8 8 hp 264.000
#> 62 19.7 6 hp 175.000
#> 63 15.0 8 hp 335.000
#> 64 21.4 4 hp 109.000
#> 65 21.0 6 drat 3.900
#> 66 21.0 6 drat 3.900
#> 67 22.8 4 drat 3.850
#> 68 21.4 6 drat 3.080
#> 69 18.7 8 drat 3.150
#> 70 18.1 6 drat 2.760
#> 71 14.3 8 drat 3.210
#> 72 24.4 4 drat 3.690
#> 73 22.8 4 drat 3.920
#> 74 19.2 6 drat 3.920
#> 75 17.8 6 drat 3.920
#> 76 16.4 8 drat 3.070
#> 77 17.3 8 drat 3.070
#> 78 15.2 8 drat 3.070
#> 79 10.4 8 drat 2.930
#> 80 10.4 8 drat 3.000
#> 81 14.7 8 drat 3.230
#> 82 32.4 4 drat 4.080
#> 83 30.4 4 drat 4.930
#> 84 33.9 4 drat 4.220
#> 85 21.5 4 drat 3.700
#> 86 15.5 8 drat 2.760
#> 87 15.2 8 drat 3.150
#> 88 13.3 8 drat 3.730
#> 89 19.2 8 drat 3.080
#> 90 27.3 4 drat 4.080
#> 91 26.0 4 drat 4.430
#> 92 30.4 4 drat 3.770
#> 93 15.8 8 drat 4.220
#> 94 19.7 6 drat 3.620
#> 95 15.0 8 drat 3.540
#> 96 21.4 4 drat 4.110
#> 97 21.0 6 wt 2.620
#> 98 21.0 6 wt 2.875
#> 99 22.8 4 wt 2.320
#> 100 21.4 6 wt 3.215
#> 101 18.7 8 wt 3.440
#> 102 18.1 6 wt 3.460
#> 103 14.3 8 wt 3.570
#> 104 24.4 4 wt 3.190
#> 105 22.8 4 wt 3.150
#> 106 19.2 6 wt 3.440
#> 107 17.8 6 wt 3.440
#> 108 16.4 8 wt 4.070
#> 109 17.3 8 wt 3.730
#> 110 15.2 8 wt 3.780
#> 111 10.4 8 wt 5.250
#> 112 10.4 8 wt 5.424
#> 113 14.7 8 wt 5.345
#> 114 32.4 4 wt 2.200
#> 115 30.4 4 wt 1.615
#> 116 33.9 4 wt 1.835
#> 117 21.5 4 wt 2.465
#> 118 15.5 8 wt 3.520
#> 119 15.2 8 wt 3.435
#> 120 13.3 8 wt 3.840
#> 121 19.2 8 wt 3.845
#> 122 27.3 4 wt 1.935
#> 123 26.0 4 wt 2.140
#> 124 30.4 4 wt 1.513
#> 125 15.8 8 wt 3.170
#> 126 19.7 6 wt 2.770
#> 127 15.0 8 wt 3.570
#> 128 21.4 4 wt 2.780
#> 129 21.0 6 qsec 16.460
#> 130 21.0 6 qsec 17.020
#> 131 22.8 4 qsec 18.610
#> 132 21.4 6 qsec 19.440
#> 133 18.7 8 qsec 17.020
#> 134 18.1 6 qsec 20.220
#> 135 14.3 8 qsec 15.840
#> 136 24.4 4 qsec 20.000
#> 137 22.8 4 qsec 22.900
#> 138 19.2 6 qsec 18.300
#> 139 17.8 6 qsec 18.900
#> 140 16.4 8 qsec 17.400
#> 141 17.3 8 qsec 17.600
#> 142 15.2 8 qsec 18.000
#> 143 10.4 8 qsec 17.980
#> 144 10.4 8 qsec 17.820
#> 145 14.7 8 qsec 17.420
#> 146 32.4 4 qsec 19.470
#> 147 30.4 4 qsec 18.520
#> 148 33.9 4 qsec 19.900
#> 149 21.5 4 qsec 20.010
#> 150 15.5 8 qsec 16.870
#> 151 15.2 8 qsec 17.300
#> 152 13.3 8 qsec 15.410
#> 153 19.2 8 qsec 17.050
#> 154 27.3 4 qsec 18.900
#> 155 26.0 4 qsec 16.700
#> 156 30.4 4 qsec 16.900
#> 157 15.8 8 qsec 14.500
#> 158 19.7 6 qsec 15.500
#> 159 15.0 8 qsec 14.600
#> 160 21.4 4 qsec 18.600
#> 161 21.0 6 vs 0.000
#> 162 21.0 6 vs 0.000
#> 163 22.8 4 vs 1.000
#> 164 21.4 6 vs 1.000
#> 165 18.7 8 vs 0.000
#> 166 18.1 6 vs 1.000
#> 167 14.3 8 vs 0.000
#> 168 24.4 4 vs 1.000
#> 169 22.8 4 vs 1.000
#> 170 19.2 6 vs 1.000
#> 171 17.8 6 vs 1.000
#> 172 16.4 8 vs 0.000
#> 173 17.3 8 vs 0.000
#> 174 15.2 8 vs 0.000
#> 175 10.4 8 vs 0.000
#> 176 10.4 8 vs 0.000
#> 177 14.7 8 vs 0.000
#> 178 32.4 4 vs 1.000
#> 179 30.4 4 vs 1.000
#> 180 33.9 4 vs 1.000
#> 181 21.5 4 vs 1.000
#> 182 15.5 8 vs 0.000
#> 183 15.2 8 vs 0.000
#> 184 13.3 8 vs 0.000
#> 185 19.2 8 vs 0.000
#> 186 27.3 4 vs 1.000
#> 187 26.0 4 vs 0.000
#> 188 30.4 4 vs 1.000
#> 189 15.8 8 vs 0.000
#> 190 19.7 6 vs 0.000
#> 191 15.0 8 vs 0.000
#> 192 21.4 4 vs 1.000
#> 193 21.0 6 am 1.000
#> 194 21.0 6 am 1.000
#> 195 22.8 4 am 1.000
#> 196 21.4 6 am 0.000
#> 197 18.7 8 am 0.000
#> 198 18.1 6 am 0.000
#> 199 14.3 8 am 0.000
#> 200 24.4 4 am 0.000
#> 201 22.8 4 am 0.000
#> 202 19.2 6 am 0.000
#> 203 17.8 6 am 0.000
#> 204 16.4 8 am 0.000
#> 205 17.3 8 am 0.000
#> 206 15.2 8 am 0.000
#> 207 10.4 8 am 0.000
#> 208 10.4 8 am 0.000
#> 209 14.7 8 am 0.000
#> 210 32.4 4 am 1.000
#> 211 30.4 4 am 1.000
#> 212 33.9 4 am 1.000
#> 213 21.5 4 am 0.000
#> 214 15.5 8 am 0.000
#> 215 15.2 8 am 0.000
#> 216 13.3 8 am 0.000
#> 217 19.2 8 am 0.000
#> 218 27.3 4 am 1.000
#> 219 26.0 4 am 1.000
#> 220 30.4 4 am 1.000
#> 221 15.8 8 am 1.000
#> 222 19.7 6 am 1.000
#> 223 15.0 8 am 1.000
#> 224 21.4 4 am 1.000
#> 225 21.0 6 gear 4.000
#> 226 21.0 6 gear 4.000
#> 227 22.8 4 gear 4.000
#> 228 21.4 6 gear 3.000
#> 229 18.7 8 gear 3.000
#> 230 18.1 6 gear 3.000
#> 231 14.3 8 gear 3.000
#> 232 24.4 4 gear 4.000
#> 233 22.8 4 gear 4.000
#> 234 19.2 6 gear 4.000
#> 235 17.8 6 gear 4.000
#> 236 16.4 8 gear 3.000
#> 237 17.3 8 gear 3.000
#> 238 15.2 8 gear 3.000
#> 239 10.4 8 gear 3.000
#> 240 10.4 8 gear 3.000
#> 241 14.7 8 gear 3.000
#> 242 32.4 4 gear 4.000
#> 243 30.4 4 gear 4.000
#> 244 33.9 4 gear 4.000
#> 245 21.5 4 gear 3.000
#> 246 15.5 8 gear 3.000
#> 247 15.2 8 gear 3.000
#> 248 13.3 8 gear 3.000
#> 249 19.2 8 gear 3.000
#> 250 27.3 4 gear 4.000
#> 251 26.0 4 gear 5.000
#> 252 30.4 4 gear 5.000
#> 253 15.8 8 gear 5.000
#> 254 19.7 6 gear 5.000
#> 255 15.0 8 gear 5.000
#> 256 21.4 4 gear 4.000
#> 257 21.0 6 carb 4.000
#> 258 21.0 6 carb 4.000
#> 259 22.8 4 carb 1.000
#> 260 21.4 6 carb 1.000
#> 261 18.7 8 carb 2.000
#> 262 18.1 6 carb 1.000
#> 263 14.3 8 carb 4.000
#> 264 24.4 4 carb 2.000
#> 265 22.8 4 carb 2.000
#> 266 19.2 6 carb 4.000
#> 267 17.8 6 carb 4.000
#> 268 16.4 8 carb 3.000
#> 269 17.3 8 carb 3.000
#> 270 15.2 8 carb 3.000
#> 271 10.4 8 carb 4.000
#> 272 10.4 8 carb 4.000
#> 273 14.7 8 carb 4.000
#> 274 32.4 4 carb 1.000
#> 275 30.4 4 carb 2.000
#> 276 33.9 4 carb 1.000
#> 277 21.5 4 carb 1.000
#> 278 15.5 8 carb 2.000
#> 279 15.2 8 carb 2.000
#> 280 13.3 8 carb 4.000
#> 281 19.2 8 carb 2.000
#> 282 27.3 4 carb 1.000
#> 283 26.0 4 carb 2.000
#> 284 30.4 4 carb 2.000
#> 285 15.8 8 carb 4.000
#> 286 19.7 6 carb 6.000
#> 287 15.0 8 carb 8.000
#> 288 21.4 4 carb 2.000
Created on 2018-04-24 by the reprex package (v0.2.0).
来源:https://stackoverflow.com/questions/50001012/excluding-multiple-columns-based-on-unquote-splicing