在R函数中粘贴变量名

时间:2012-04-04 04:28:28

标签: debugging r function

借助flodelfound 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

现在,这就是我被困住的地方。

任何人都可以告诉我需要阅读哪些手册页,或者可能是如何解决这个问题的友好提示?

感谢您的阅读。

3 个答案:

答案 0 :(得分:4)

这是因为您将profession传递给ADDlookup函数,但它尚不存在。

你编写函数的方式,你必须区分使用包含变量名称的字符向量变量本身

例如,您的前几行paste(originalDF,'$',originalVAR,sep='')等似乎期望originalDForiginalVAR成为字符串,您将拥有{{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"]]