2013-05-10 2 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()를 호출 해 보았지만 작동하지 않습니다. 사전에

감사합니다, C

+1

사이드 노트 : 왜 단순히'as.numeric (GSUB를 ("[^ 0-9 \\ .] "," ", df1 $ V2))'그 다음 'NA'값을 확인 하시겠습니까? – joran

+0

아주 좋은 지적! – Chris

답변

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

에 동의하고 require (stringr)를 생략하여 죄송합니다 ... – Chris

1

I는이 작업을 수행하는 다소 해키 방법입니다,하지만 당신은 $에 다음 strsplitsubstitue을 사용할 수 느끼지만, 이것은 당신이 항상 그것의 이름을 사용하여 열을 전화 가정 $. 어쨌든, 당신은

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

두 개의 인수, 즉 전체 데이터 프레임과 원하는 열의 이름 또는 인덱스를 받아들이도록 함수를 변경하는 것이 좋습니다. – joran

+0

@ 죠란 그것은 훨씬 더 나은 해결책이 될 것이고 아주 쉽게 깨지 않을 것입니다! 어쩌면 해결책으로 추가해야할까요? –

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