基于非引号拼接排除多个列(!!!)

时间:2018-04-24 11:53:19

标签: r tidyr tidyeval tidyselect

尝试排除

    调用tidyr::gather() 时,
  • 多个
  • 通过字符向量参数(shiny::selectInput的输出)而不是通过...
  • 作为我的函数的输入
  • 采用程序化方式

如何通过整洁的评估功能实现这一目标?

由于我通过单个函数参数传递多个列名,我认为我需要使用!!!(非引号拼接)而不是Programming with dplyr中列出的!!。但这似乎与tidyselect::vars_select()很好地配合,似乎-造成了麻烦。

这是我想要做的基本事情:

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

但是我想通过单个参数传递列名称(如同闪亮的应用程序一样,它也将通过input$<select_input_id>提供):

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

然后我试着看看-是否是问题:

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

这似乎有效。

然后我尝试将-放入实际的符号名称中,但这不起作用(至少我尝试过的方式; - )):

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

修改

在莱昂内尔的帮助下,我能够把它拼凑起来:

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

甚至简化:

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

reprex package(v0.2.0)创建于2018-04-26。

1 个答案:

答案 0 :(得分:5)

您需要取消引用拼接表达式列表,而不是符号列表。例如:

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

reprex package(v0.2.0)创建于2018-04-24。