借助flodel我found a way to replace numeric codes with value labels from a lookup table。
像我一样雄心勃勃,我现在想把它变成一个功能。此外,我有很多查找表,我需要抓住我的数据,所以一个功能将是方便的。
但首先是一些样本数据,从数据框架开始,
df <- data.frame(id = c(1:6),
profession = c(1, 5, 4, NA, 0, 5))
df
# id profession
# 1 1
# 2 5
# 3 4
# 4 NA
# 5 0
# 6 5
以及包含有关行业代码的人类可读信息的查找表,
profession.lookuptable <- c(Optometrists=1, Accountants=2, Veterinarians=3,
`Financial analysts`=4, Nurses=5)
flodel告诉我how replace numeric codes with value labels from a lookup table。像这样,
match.idx <- match(df$profession, profession.lookuptable)
df$profession <- ifelse(is.na(match.idx),
df$profession, names(profession.lookuptable)[match.idx])
df
# id profession
# 1 Optometrists
# 2 Nurses
# 3 Financial analysts
# 4 <NA>
# 5 0
# 6 Nurses
我现在想把它放到一个函数中,我可以在其中声明数据框df
和变量profession
的名称,并让函数处理其余部分。
我定义了这样的函数,
ADDlookup <- function(orginalDF, orginalVAR) {
DF.VAR <- paste(orginalDF, "$", orginalVAR, sep="")
lookup.table <- paste(orginalVAR, ".lookuptable")
match.idx <- match(DF.VAR, lookup.table)
DF.VAR <- ifelse(is.na(match.idx), DF.VAR, names(lookup.table)[match.idx])
}
但显然这不起作用
ADDlookup(df, profession)
我得到了错误的混乱
Error in paste(orginalDF, "$", orginalVAR, sep = "") :
object 'profession' not found
现在,这就是我被困住的地方。
任何人都可以告诉我需要阅读哪些手册页,或者可能是如何解决这个问题的友好提示?
感谢您的阅读。
答案 0 :(得分:4)
这是因为您将profession
传递给ADDlookup
函数,但它尚不存在。
你编写函数的方式,你必须区分使用包含变量名称的字符向量和变量本身。
例如,您的前几行paste(originalDF,'$',originalVAR,sep='')
等似乎期望originalDF
和originalVAR
成为字符串,您将拥有{{1}成为字符串 DF.VAR
。但是,当您执行'df$profession'
时,您希望match
成为变量 DF.VAR
。
这就是我建议您解决的问题:
- 传递df$profession
作为对象,originalDF
- 传递df
作为字符串,为originalVAR
(它是一个列名,因此是一个字符串)
然后,通过以下方式从数据框中检索'profession'
中包含的列:
originalVar
现在你寻找对象DF.VAR <- originalDF[,originalVAR] # e.g. df[,'profession']
的下一行有点棘手:你构造字符串 profession.lookuptable
,然后你想要查找具有该名称的对象。
为此,您可以使用'profession.lookuptable'
(get
)。 ?get
将返回get('df')
数据框:
df
这将检索名为lookup.table <- get(paste(orginalVAR, "lookuptable",sep='.'))
的对象。它遵循与您直接键入'profession.lookuptable'
相同的规则,因此您必须确保该函数可以“看到”该对象(在您的情况下,您应该没问题)。
接下来,您似乎想要返回profession.lookuptable
数据框,其中originalDF
列已被查找值替换。
我只需修改originalVAR
列,将其替换为查找值:
originalDF[,originalVAR]
注意我们不实际修改您作为originalDF[,originalVAR] <-
ifelse(is.na(match.idx), DF.VAR, names(lookup.table)[match.idx])
参数传入的df
数据框; R在函数内创建数据帧的副本。因此,您的原始ADDlookup
会被保留。
最后,我们必须返回数据框:
df
现在一起:
return(originalDF)
现在来测试一下:
ADDlookup <- function(orginalDF, orginalVAR) {
# retrieve the originalVAR column of originalDF
DF.VAR <- originalDF[,originalVAR]
# find the variable called {originalVAR}.lookuptable
lookup.table <- get(paste(originalVAR, "lookuptable",sep='.'))
# look up the values
match.idx <- match(DF.VAR, lookup.table)
# replace the originalVAR column with the looked-up values
originalDF[,originalVAR] <-
ifelse(is.na(match.idx), DF.VAR, names(lookup.table)[match.idx])
# return the modified data frame
return(originalDF)
}
请注意,原始> ADDlookup(df,'profession')
id profession
1 1 Optometrists
2 2 Nurses
3 3 Financial analysts
4 4 <NA>
5 5 0
6 6 Nurses
未经修改;一般来说,R函数不修改传递给它们的参数。
作为另一项改进 - 在调用df
函数之前依赖已创建的professions.lookup
表通常有点危险。
而不是整个ADDlookup
shebang(取决于你是否在各种范围内有多个'profession.lookup'表),我强烈建议你只需将查找表作为参数传递:< / p>
lookup.table <- get( 'profession.lookup' )
然后你可以避免整个ADDlookup <- function( originalDF, originalVAR, lookup.table )
行(以及与之相关的所有相关范围问题)。
然后你通过以下方式调用该函数:
get(xxxx)
答案 1 :(得分:3)
当然,有一些更复杂的方法可以按照您最初设想的方式使其工作,但简单地重新组织此功能的工作方式会更简单,更简单:
ADDLookup <- function(originalDF,var,varLookup){
match.idx <- match(originalDF[,var], varLookup)
originalDF[,var] <- ifelse(is.na(match.idx),
originalDF[,var], names(varLookup)[match.idx])
originalDF
}
ADDLookup(df,"profession",profession.lookuptable)
id profession
1 1 Optometrists
2 2 Nurses
3 3 Financial analysts
4 4 <NA>
5 5 0
6 6 Nurses
请注意,现在我传递数据框df
,有问题的变量名称,var
作为文字字符,查找表本身作为参数。
此外,您现在已经了解了为什么$
在交互使用中比在编程中使用更多!因为它与传递给函数的参数没有很好地匹配。对于这种类型的任务,您需要[
语法。
答案 2 :(得分:0)
我将查找表定义为因子。
df[,"profession"] <- profession.lookuptable[df[,"profession"]]