如何使用dplyr参数变量名称

时间:2017-08-25 07:32:59

标签: r dplyr

如果我的头衔不是很好,我很抱歉,如果有人有更好的头衔,请加强它。

我目前正在努力使用新的dplyr 0.7,它可以使用dplyr在我自己的函数中使用变量。我不知道我尝试的是不可能的,还是我采取了错误的方式。

我有一个简单的数据框,每个公司有一行,每个公司有一堆2015年和2014年的变量:

class NERComboTagger(StanfordNERTagger):

  def __init__(self, *args, **kwargs):
    self.stanford_ner_models = kwargs['stanford_ner_models']
    kwargs.pop("stanford_ner_models")
    super(NERComboTagger,self).__init__(*args, **kwargs)

  @property
  def _cmd(self):
    return ['edu.stanford.nlp.ie.NERClassifierCombiner',
            '-ner.model',
            self.stanford_ner_models,
            '-textFile',
            self._input_file_path,
#            '-outputFormat',
#            self._FORMAT,
            '-ner.applyNumericClassifiers',
            'true',
#            '-ner.useSUTime',
#            'false',
            '-regexner.mapping',
            'edu/stanford/nlp/models/kbp/cn_regexner_mapping.tab',
            '-regexner.validpospattern',
            '^(NR|NN|JJ).*',
            '-regexner.ignorecase',
            'true']

我希望能够为每个变量创建一个“evo”变量,该变量基本上是2015年的值减去2013年的值。

在我的例子中,我想得到一个名为evoCA的变量,它等于CA2015 - CA2014,以及一个名为evoVA的变量,它等于VA2015 - VA2014。

(基本上:

evo <- data.frame(id=1:5,
              CA2015 = c(1200,1500,1550,200,0),
              CA2014 = c(800,50,654,8555,0),
              VA2015 = c(6984,6588,633,355,84),
              VA2014 = c(35,358,358,1331,86))

所以我试着创建一个函数来接受我想要变量的变量的名称参数,但我不能使它工作。这是我能做的最好的事情:

evo %>%
  mutate(evoCA= CA2015 - CA2014,
     evoVA = VA2015 - VA2014)

}

但它不是很干净,因为我不仅要传递变量名,还要传递带有后缀的变量。

有什么想让它变得更好?

2 个答案:

答案 0 :(得分:2)

这是一个不需要编写新功能的解决方案:

library(dplyr)
evo <- data.frame(id=1:5,
                  CA2015 = c(1200,1500,1550,200,0),
                  CA2014 = c(800,50,654,8555,0),
                  VA2015 = c(6984,6588,633,355,84),
                  VA2014 = c(35,358,358,1331,86))

# This creates two dataframes with the same properties and two diff years
evo2014 <- evo %>%
  select(contains("2014"))
evo2015 <- evo %>%
  select(contains("2015"))

# If both have the same amount of columns make a matrix subtraction and obtain the difference. Then bind the difference dataframe to the original df
if (ncol(evo2014) == ncol(evo2015)) {
  evodiff <- as.matrix(evo2015 - evo2014)
  varnames <- substr(colnames(evo2014), 1, 2)
  colnames(evodiff) <- paste0("evo", varnames)
  evo <- bind_cols(evo, as.data.frame(evodiff))
}
evo
#>   id CA2015 CA2014 VA2015 VA2014 evoCA evoVA
#> 1  1   1200    800   6984     35   400  6949
#> 2  2   1500     50   6588    358  1450  6230
#> 3  3   1550    654    633    358   896   275
#> 4  4    200   8555    355   1331 -8355  -976
#> 5  5      0      0     84     86     0    -2

答案 1 :(得分:1)

使用tidyr,您可以将数据转换为更整洁的数据。

如果年份总是相同的两年且前缀总是在年之前,那么类似的东西可以添加你想要的所有列:

evo <- data.frame(id=1:5,
                  CA2015 = c(1200,1500,1550,200,0),
                  CA2014 = c(800,50,654,8555,0),
                  VA2015 = c(6984,6588,633,355,84),
                  VA2014 = c(35,358,358,1331,86))
library(dplyr, warn.conflicts = F)
library(tidyr, warn.conflicts = F)
evo %>%
  gather(key = "type", value = "value", -id) %>%
  separate(type, c("prefix", "year"), sep = -5) %>%
  spread(year, value) %>%
  mutate(evo = `2015` - `2014`) %>%
  gather(key = "key", value = "value", -(id:prefix)) %>%
  unite("type", prefix:key, sep = "") %>%
  spread(type, value) %>%
  select(id, ends_with("2015"), ends_with("2014"), ends_with("evo"))
#>   id CA2015 VA2015 CA2014 VA2014 CAevo VAevo
#> 1  1   1200   6984    800     35   400  6949
#> 2  2   1500   6588     50    358  1450  6230
#> 3  3   1550    633    654    358   896   275
#> 4  4    200    355   8555   1331 -8355  -976
#> 5  5      0     84      0     86     0    -2

如果这两年与2014年和2015年不同,您也可以发挥作用。