从传递给函数的列名派生变量

时间:2013-05-10 21:58:16

标签: r

我已经掌握了一些非常混乱的数据,并且我编写了一个函数来进行一些转换(字符串到数字),我很乐意改进它。基本上该函数采用凌乱的字符数据向量并将数据转换为数字。

例如:

##  say you had this
df1 <- data.frame ( V1 = c("   $25.25", "4,828", "      $7,253"), V2 = c( "THIS is bad data", "725", "*error"))

numconv <- function(vec){
    vec <- str_trim(vec)
    vec <- gsub(",|\\$", "", vec)
    if( sum(!grepl( "[0-9]",vec)) == 0){
        vec <- as.numeric(vec)
    }
    if( sum(!grepl( "[0-9]",vec)) != 0){
        print("!!ERROR STRANGE CHARACTERS!!")
    }
}

df1$V1recode <- numconv(df1$V1)
df1$V2recode <- numconv(df1$V2)
[1] "!!ERROR STRANGE CHARACTERS!!"

如何在函数中指定原始列名的名称,以便将其粘贴到函数中的错误消息中,因此它显示为:

!! V2中的错误角色!!

我已尝试在函数中调用names()和colnames(),但这似乎不起作用。

提前致谢, ç

3 个答案:

答案 0 :(得分:2)

旧的deparse(substitute(.))技巧似乎有效。

numconv <- function(vec){nam <- deparse(substitute(vec))
    vec <- gsub(" ","", vec)
    vec <- gsub(",|\\$", "", vec)
    if( sum(!grepl( "[0-9]",vec)) == 0){
        vec <- as.numeric(vec)
    }
    if( sum(!grepl( "[0-9]",vec)) != 0){
        print(paste("!!ERROR STRANGE CHARACTERS!!", nam) )
    }
}
df1$V2recode <- numconv(df1$V2)
# [1] "!!ERROR STRANGE CHARACTERS!! df1$V2"

(我没有加载stringr,因为我认为gsub调用效率更高。)

答案 1 :(得分:1)

我认为这是一种有点hacky方式,但您可以在substitue上使用strsplit然后$,但这假设您始终使用其名称调用列与$。无论如何,您可以使用此名称获取列名称并将其粘贴到您希望的错误消息中......

    x <- strsplit(as.character( substitute(vec) ) ,"$" )[[3]]

答案 2 :(得分:1)

关键是将重新编码包装到函数中。这样,您就可以跟踪正在处理的列,从而将列名放入警告消息中。以下函数重新编码'col_names'参数中列出的数据框的任何列(如果保留null,则该函数适用于所有列)。该函数返回原始数据框,以及将flag中的字符串添加到列名称的重新编码列。

require(stringr)

df1 <- data.frame (
  V1 = c("   $25.25", "4,828", "      $7,253"), 
  V2 = c( "THIS is bad data", "725", "*error"))

numconv <- function(df, col_names = NULL, flag = "recode"){

  if(is.null(col_names)) {
    col_names <- colnames(df)
  }
    out <- lapply(1:length(col_names), function(i) {
      vec <- str_trim(df[,col_names[i]])
      vec <- gsub(",|\\$", "", vec)
      if( sum(!grepl( "[0-9]",vec)) == 0){
        vec <- as.numeric(vec)
      }
      if( sum(!grepl( "[0-9]",vec)) != 0){
        print(paste("!!ERROR STRANGE CHARACTERS in", col_names[i], "!!"))
      }
      vec
    })

    out <- data.frame(out, stringsAsFactors = FALSE)
    colnames(out) <- paste(col_names, flag, sep = "")
    cbind(df, out)
}

numconv(df1)
[1] "!!ERROR STRANGE CHARACTERS in V2 !!"
V1               V2 V1recode         V2recode
1       $25.25 THIS is bad data    25.25 THIS is bad data
2        4,828              725  4828.00              725
3       $7,253           *error  7253.00           *error