我想在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),但结果是相同的。
有人可以告诉我发生了什么或建议一些可行的代码吗?
答案 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
代替。