使用`{`大括号来获取dplyr中分散列的名称

时间:2018-08-28 10:49:31

标签: r dplyr

stocksm <- structure(list(time = structure(c(14245, 14246, 14247, 14248, 
14249, 14250, 14251, 14252, 14253, 14254, 14245, 14246, 14247, 
14248, 14249, 14250, 14251, 14252, 14253, 14254, 14245, 14246, 
14247, 14248, 14249, 14250, 14251, 14252, 14253, 14254), class = "Date"), 
stock = c("X", "X", "X", "X", "X", "X", "X", "X", "X", "X", 
"Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Y", "Z", "Z", 
"Z", "Z", "Z", "Z", "Z", "Z", "Z", "Z"), price = c(0.239252107606609, 
-1.56883100623924, 0.712087445800904, 0.0978227160929474, 
-0.591439041236675, -0.430019034335168, 0.033727039296972, 
-0.172634546678134, -1.30235342173481, 0.0186726500971933, 
3.13359212567755, -3.1308982249284, -0.00666262981780505, 
0.446884242347021, 0.865122586467621, -0.283571611040151, 
-0.108833395864396, -2.18319153514799, -0.27483222045657, 
0.445347442843193, -2.86909424204074, -3.46188641965012, 
0.144189534381867, -14.8137095357316, -2.11457178683177, 
3.23603451612312, -2.79876705700199, 0.824675151918647, -2.44132963041655, 
-2.97946926198463)), row.names = c(NA, -30L), class = "data.frame")

我想编写一个dplyr函数,该函数仅对spread ed函数执行一些操作。我有一个下面的代码,我想概括一下。但是,由于我想散布任意输入的列,因此我需要一种除unique(.$stock)之外的另一种捕获其子组的方法,因为我无法将$子集与任意var一起使用。

stocksm %>% {
  variables <- unique(.$stock)
  spread(., stock, price) %>% mutate_at(vars(variables), ~.)
}

我想到的是一个像这样的函数:

mutate_subgroups <- function(data, var){
  var <- enquo(var)

  data %>% {
    variables <- . %>% pull(!! var) %>% unique()
    spread(., data, value) %>% mutate_at(vars(variables), ~.)
  }
}

但是. %>% pull(stock) %>% unique()的计算结果为:

  

错误:variables必须求和列位置或名称,而不是函数

那么我如何获得可以在mutate_at中进一步使用的变量的名称?为什么实际上. %>% pull(stock) %>% unique()不起作用?

1 个答案:

答案 0 :(得分:1)

您可以尝试

mutate_subgroups <- function(data){
 data %>% 
 spread(stock, price) %>% 
  mutate_at(vars(-matches(paste(colnames(data), collapse = "|"))),~.+100)}

mutate_subgroups(stocksm)
         time         X         Y         Z
1  2009-01-01 100.23925 103.13359  97.13091
2  2009-01-02  98.43117  96.86910  96.53811
3  2009-01-03 100.71209  99.99334 100.14419
4  2009-01-04 100.09782 100.44688  85.18629
5  2009-01-05  99.40856 100.86512  97.88543
6  2009-01-06  99.56998  99.71643 103.23603
7  2009-01-07 100.03373  99.89117  97.20123
8  2009-01-08  99.82737  97.81681 100.82468
9  2009-01-09  98.69765  99.72517  97.55867
10 2009-01-10 100.01867 100.44535  97.02053

该想法是使用-matches排除父data.frame的同名。添加了+100来说明仅对扩展的输出列的影响。

当您想要一种类似于代码的方法时,可以尝试一下。由于variables是引导程序,因此您需要使用syms才能成功调用mutate_at

mutate_subgroups <- function(data, var){
  var <- enquo(var)
  variables <- data %>% 
                pull(!!var) %>% 
                unique()
  data %>% 
    spread(., stock, price) %>% 
    mutate_at(vars(!!!rlang::syms(variables)), ~.+100)
}
mutate_subgroups(stocksm, stock)