2013-05-10 60 views
1

我已經掌握了一些非常混亂的數據,並且編寫了一些函數來完成一些轉換(字符串到數字),我很想改進它。基本上這個函數需要一個混亂的字符數據向量並將數據轉換爲數字。從傳遞給函數的列名導出變量

例如:

## 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(),但這似乎不起作用。

由於提前, Ç

+1

邊注:爲什麼不直接'as.numeric(GSUB(「[^ 0-9 \\ 。]「,」「,df1 $ V2))'然後檢查」NA「值? – joran 2013-05-10 22:18:17

+0

非常好的一點! – Chris 2013-05-10 23:15:49

回答

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" 

(因爲我想到了一個電話GSUB會更有效我沒有加載stringr。)

+0

同意了,並遺憾地要求(stringr)... – Chris 2013-05-10 23:16:37

1

我覺得這是要做到這一點有點哈克的方式,但你可以在$使用substitue然後strsplit,但這種假設你使用它的名字總是具有調用列$。無論如何,你可以使用此得到列名並將其粘貼到一個錯誤信息,如你所願......

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

我打算建議改變函數以接受兩個參數:整個數據框以及所需列的名稱或索引。 – joran 2013-05-10 22:17:29

+0

@joran這將是一個更好的解決方案,並不會輕易破壞!也許你應該添加它作爲解決方案? – 2013-05-10 22:19:41

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 
+0

非常酷!雖然在我的特殊用例中,我更喜歡對列進行控制,但這是例外。超越! – Chris 2013-05-10 23:20:52