自定义函数

时间:2018-03-29 20:12:45

标签: r

我想在R中创建一个函数,它将根据字符/分类列创建一个数字列。为了做到这一点,我需要在分类列中获取不同的值。我可以在一个函数之外做到这一点,但是想做一个可重用的函数来做它。我遇到的问题是,在函数外部工作的相同distinct()公式在公式中的行为方式不同。我在下面创建了一个演示:

# test of call to db to numericize
DF <- data.frame("a" = c("a","b","c","a","b","c"),
                 "b" = paste(0:5, ".1", sep = ""),
                 "c" = letters[1:6],
                 stringsAsFactors = FALSE)

catnum <- function(db, inputcolname) {
  x <- distinct(db,inputcolname);
  print(x);
  return(x);
}

y <- distinct(DF,a)
y
catnum(DF,'a')

虽然y给出了正确的不同的一列答案(其中一列有(a,b,c)),但函数中的x是整个数据帧。我曾尝试使用和不使用&#39; &#39;,如catnum(DF,a),但结果是相同的。

有人可以告诉我发生了什么或建议一些可行的代码吗?

3 个答案:

答案 0 :(得分:2)

一种解决方案是在函数内部使用distinct_函数。 distinct期望列名称,它不适用于variable中的列名称。

例如distinct(DF, "a")无效。实际语法是:distinct(DF, a)。注意缺少的quotes。当从函数调用distinct时,列名作为变量名(即inputcolname)提供,并进行了评估。因此意外的结果。但distinct_适用于列的变量名称。

library(dplyr)
catnum <- function(db, inputcolname) {
  x <- distinct_(db,inputcolname);
  #print(x);
  return(x);
}
#With modified function results were as expected.
catnum(DF,'a')
# a
# 1 a
# 2 b
# 3 c

答案 1 :(得分:1)

不确定您要执行的操作以及distinct函数的来源。你在找这个吗?

catnum<-function(DF,var){
  length(unique(DF[[var]]))
}
catnum(DF,'a')

答案 2 :(得分:1)

您的输入不一样,因此您会得到不同的结果。如果您为distinct提供catnum相同的参数,则会得到相同的结果:

isTRUE(all.equal(distinct(DF, a),
                 catnum(DF, "a")))
## [1] FALSE
isTRUE(all.equal(distinct(DF, "a"),
                 catnum(DF, "a")))
##[1] TRUE

不幸的是,这不起作用:

catnum(DF, a)
##   a   b c
## 1 a 0.1 a
## 2 b 1.1 b
## 3 c 2.1 c
## 4 a 3.1 d
## 5 b 4.1 e
## 6 c 5.1 f

原因,如

中所述
vignette("programming")

如果你想编写使用dplyr函数的函数,你必须跳过几个讨厌的箍。解决方案(正如您将在插图中了解到的)如下:

catnum <- function(db, inputcolname) {
  inputcolname <- enquo(inputcolname)  
  distinct(db, !!inputcolname)
}

catnum(DF, a)
##   a
## 1 a
## 2 b
## 3 c

或者你可以得出结论,这太令人困惑了,并且做了像

这样的事情
catnum <- function(db, inputcolname) {
  unique(db[, inputcolname, drop = FALSE])
}

catnum(DF, "a")
##   a
## 1 a
## 2 b
## 3 c

代替。