2015-01-28 2 views
0

특정 폴더에서 모두 동일한 구조의 CSV 파일을 읽습니다. 또한 dataFrame에 특정 값을 추가하는 함수를 만들었습니다.특정 폴더의 모든 csv 파일에 함수 적용

"폴더 읽기"- 부분을 만들었고 함수도 만들었습니다. 그러나 이제는이 두 가지를 서로 연결해야합니다.

다음

내 코드입니다 :

addValue <- function(valueToAdd, df.file, writterPath) { 
    df.file$result <- df.file$Value + valueToAdd 
    x <- x + 1 
    df.file <- as.data.frame(do.call(cbind, df.file)) 
    fullFilePath <- paste(writterPath, x , "myFile.csv", sep="") 
    write.csv(as.data.frame(df.file), fullFilePath) 
} 

#1.reading R files 
path <- "C:/Users/RFiles/files/" 
files <- list.files(path=path, pattern="*.csv") 
for(file in files) 
{ 
    perpos <- which(strsplit(file, "")[[1]]==".") 
    assign(
    gsub(" ","",substr(file, 1, perpos-1)), 
    read.csv(paste(path,file,sep=""))) 
} 

#2.appyling function 
writterPath <- "C:/Users/RFiles/files/results/" 
addValue(2, sys, writterPath) 

어떻게 내 #1.reading R files 구조에 addValue() 기능을 적용하기 위해 내가하는 데 문제가있는 곳은? 어떤 추천?

답변 해 주셔서 감사합니다.

UPDATE가

이 예제 코드를하려고 할 때 내가 얻을 :

+ } 
+ ## If you really need to change filenames with numbers, 
+ newfname <- file.path(npath, paste0(x, basename(fname))) 
+ ## otherwise just use `file.path(npath, basename(fname))`. 
+ 
+ ## (4) Write back to a different file location: 
+ write.csv(newdat, file = newfname, row.names = FALSE) 
+ } 
Error in `$<-.data.frame`(`*tmp*`, "results", value = numeric(0)) : 
    replacement has 0 rows, data has 11 

어떤 제안?

+0

어떤 문제가 있습니까? ('list.files()'에 대한 호출에서'full.names = TRUE'가 필요합니까?) – r2evans

+0

@ r2evans Thx 답장을 보내주십시오! 내 문제는 내''Rread' 파일 구조에'addValue()'함수를 적용하는 법을 모른다는 것입니다. Atm이 두 가지는 서로 완전히 별개입니다 ... – mrquad

답변

1

코드에 몇 가지 문제가 있습니다 (예 : 함수에서 x이 정의되지 않고 addValue 사이의 호출간에 유지되지 않음). 따라서이 코드는 실제 코드의 잘린 버전이고 아직도 잔재물이 남아 있습니다. 코드를 따로 따로 선택하는 대신, 필자는 제안 된 코드와 몇 가지 지침을 제공 할 것입니다.

addValue은 data.frame을 변경하는 것이 좋지만 적어도 파일 이름을 추측하지는 않았으므로 파일을 디스크에 쓰고 기존 파일을 덮어 쓸 수도 있습니다. 파일).

(1) 파일을 읽으려고하고, (2) 값을 추가하고, (3) 전역 변수에 할당하고, (4) 디스크에 기록하려고합니다. 세 번째는 문제가 될 수 있으며 (일부 프로그래머에게는 논쟁의 여지가 있습니다), 지금 당장 떠날 것입니다.

디스크에 쓰는 것이 data.frame에 "가치 추가"아이디어가 내재하지 않는 한 # 4를 # 4와 별도로 유지하는 것이 좋습니다. 다음은 코드 대신 사용할 수있는 대체 코드입니다.

addValue <- function(valueToAdd, df) { 
    df$results <- df$Value + valueToAdd 
    ## more stuff here? 
    return(df) 
} 

opath <- 'c:/Users/RFiles/files/raw'  # notice the difference 
npath <- 'c:/Users/RFiles/files/adjusted' 
files <- list.files(path = opath, pattern = '*.csv', full.names = TRUE) 

x <- 0 
for (fname in files) { 
    x <- x + 1 
    ## (1) read in and (2) "add value" to it 
    dat <- read.csv(fname) 
    newdat <- addValue(2, dat) 

    ## (3) Conditionally assign to a global variable: 
    varname <- gsub('\\.[^.]*$', '', basename(fname)) 
    if (! exists(varname)) { 
     assign(x = varname, value = newdat) 
    } else { 
     warning('variable exists, did not overwrite: ', varname) 
    } 
    ## If you really need to change filenames with numbers, 
    newfname <- file.path(npath, paste0(x, basename(fname))) 
    ## otherwise just use `file.path(npath, basename(fname))`. 

    ## (4) Write back to a different file location: 
    write.csv(newdat, file = newfname, row.names = FALSE) 
} 

전역 변수를 덮어 쓰지 않습니다. 이것은 성가신 수표 일지 모르지만 실수로이 코드 섹션을 실행하면 데이터를 잃지 않게됩니다.

많은 변수를 전역 주소 공간에 할당하는 대신 모두를 개를 단일 목록에 저장하는 방법이 있습니다. 형식이 동일하다고 가정하면 동일한 (또는 매우 유사한) 분석 방법으로 상대방을 처리 할 가능성이 높으므로 모든 항목을 하나의 목록에 넣으면 쉽게 처리 할 수 ​​있습니다. 서로 다른 변수 이름을 추적하는 대안은 귀찮을 수 있습니다.

## addValue as defined previously 
opath <- 'c:/Users/RFiles/files/raw' 
npath <- 'c:/Users/RFiles/files/adjusted' 
ofiles <- list.files(path = opath, pattern = '*.csv', full.names = TRUE) 
nfiles <- file.path(npath, basename(ofiles)) 

dats <- mapply(function(ofname, nfname) { 
    dat <- read.csv(ofname) 
    newdat <- addValue(2, dat) 
    write.csv(newdat, file = nfname, row.names = FALSE) 
    newdat 
}, ofiles, nfiles, SIMPLIFY = FALSE) 
length(dats)       # number of files 
names(dats)        # one for each file 
관련 문제