2014-05-16 4 views
1

여기 상황이 있습니다. 내 R 코드는 응용 프로그램의 캐시에있는 기존 RData 파일이 최신 버전인지 확인해야합니다. 나는 특정 데이터 요소의 인코딩 된 이름을 가진 파일을 base64으로 저장함으로써 그렇게한다. 그러나 각 요소에 해당하는 데이터는 요소 당 특정 SQL 쿼리를 제출하여 검색되며 데이터 카탈로그의 구성 파일에 모두 지정되어 있습니다. 따라서 요소에 대한 데이터가 검색되었지만 나중에 특정 SQL 쿼리를 변경해야하는 상황에서 데이터가 업데이트되지 않습니다.파일에서 오브젝트를 완전히로드하지 않고 R 데이터 오브젝트의 속성에 액세스 할 수 있습니까?

이 상황을 처리하기 위해 개체의 속성을 R개체로 사용하기로 결정했습니다. base64로 인코딩 - - 나는 각 데이터 객체의 해당 SQL 쿼리 (request)를 저장하려는 객체의 속성으로 : 다음

# save hash of the request's SQL query as data object's attribute, 
# so that we can detect when configuration contains modified query 
attr(data, "SQL") <- base64(request) 

, 나는 SQL이 된 쿼리가 변경되었는지 여부를 확인해야합니다, 나는 싶습니다 객체의 해당 속성을 검색하여 현재 SQL 쿼리의 해시와 비교하십시오. 서로 일치하면 - 쿼리가 변경되지 않은 내가이 데이터 요청을 처리 건너가 일치하지 않는 경우 - 쿼리가 변경되었습니다 내가 요청 처리와 진행 :

# check if the archive file has already been processed 
if (DEBUG) {message("Processing request \"", request, "\" ...")} 
if (file.exists(rdataFile)) { 
    # now check if request's SQL query hasn't been modified 
    data <- load(rdataFile) 
    if (identical(base64(request), attr(data, "SQL"))) { 
    skipped <<- skipped + 1 
    if (DEBUG) {message("Processing skipped: .Rdata file found.\n")} 
    return (invisible()) 
    } 
    rm(data) 
} 

내 질문입니다 파일에서 객체를 완전히로드하지 않고 객체의 속성 을 읽고 액세스 할 수 있는지 여부 즉 위의 코드에서 load()rm()을 피할 수 있습니까?

귀하의 의견은 대단히 감사합니다!

업데이트 : 추가 질문 : 내 코드가 잘못되어도 처리를 수행 할 때 - 모든 정보가 최신 인 경우 (캐시 및 구성 파일에 변경 사항이 없음))?

업데이트 2 (@ MrFlick의 대답에 따라 추가 코드) :

# construct name from data source prefix and data ID (see config. file), 
# so that corresponding data object (usually, data frame) will be saved 
# later under that name via save() 
dataName <- paste(dsPrefix, "data", indicator, sep = ".") 

assign(dataName, srdaGetData()) 
data <- as.name(dataName) 

# save hash of the request's SQL query as data object's attribute, 
# so that we can detect when configuration contains modified query 
attr(data, "SQL") <- base64(request) 

# save current data frame to RData file 
save(list = dataName, file = rdataFile) 
# alternatively, use do.call() as in "getFLOSSmoleDataXML.R" 

# clean up 
rm(data) 

답변

2

당신은 "정말"당신이 내 cgwtools::lsdata 기능의 코드를 수정할 수를, 그러나 수 없습니다.

function (fnam = ".Rdata") 
{ 
    x <- load(fnam, envir = environment()) 
    return(x) 
} 

로드하는 데 시간이 걸리고 잠시 메모리를 사용하면 로컬 환경이 사라집니다. 따라서 속성을 검사 할 항목에 대한 인수를 추가하십시오. 함수 내에 행을 추가하십시오. attributes(your_items) ->y ; return (list(x=x,y=y))

+0

당신을 감사 전화 당신의 대답에 대해 아주 많이! 그러나, 나는 정말로 내 접근법 ('load'을 사용하는 접근법)과 본질적인 차이점을 보지 못합니다. 내가 올바르게 이해했다면, 당신의 접근 방식의 "속임수"는 자동 사라지는 환경이지만,'rm'을 호출하고 그걸로 끝내기가 더 쉽지는 않습니다. 어떤 경우에도 객체로드가 발생합니다. 이상하게도'load'와'rm'을 사용하는 코드가 예상대로 작동하지 않습니다. 너에게 틀린 것처럼 보이는 것이 있는가? –

+1

'load'를 사용할 때 위험 할 수있는 점 중 하나는'rm'의 약간의 오자가 당신이 지키고 자했던 것들을 죽일 것이라는 것을 말하지 않기 위해서 당신이 현재 환경에서 같은 이름으로 존재하는 어떤 객체라도 폭파하게한다는 것입니다 : (-이 함수를 사용하는 이유는 무엇입니까? –

+0

이 응용 프로그램의 경우 내가 지정하는 이름은 고유하므로 구성 파일에서 가져온 것이기 때문에 확신합니다. 그러나 귀하의 요점을 이해합니다. 그리고 새로운 것을 매일 배우기 ... 그런데, 내 질문을 게시하기 전에 그 주제에 대해 연구하는 동안, 나는 재미 있고 흥미로운이 게시물을 읽었으며, 나는 당신이 읽는 것을 즐긴다 : http : // www.cybaea.net/Blogs/A-warning-on-the-R-save-format.html –

1

그리고 load()을 사용하는 방법에 문제가 있습니다. save/load을 사용하면 여러 개체를 .RData 파일로 "동결 건조"할 수 있습니다. 그들은 현재 환경에 "다시 infalte". 결과적으로 load()을 호출하면 객체가 반환되지 않고 복원 된 모든 객체의 이름이 포함 된 문자 벡터가 반환됩니다.당신이 당신의 save() 코드를 제공하지 않았기 때문에, 나는 당신의로드 파일에 실제로 무엇이 확실하지 않다, 그러나 data라는 변수 인 경우, 다음 단지

load(rdataFile) 

하지

data <- load(rdataFile) 
+0

답변 해 주셔서 감사합니다! 답을 명확히하기 위해 답마다 질문을 업데이트했습니다 (업데이트 2 참조). 데이터 파일 당 하나의 객체 만로드하므로 exp가 아닙니다. 충돌을 일으킬 수 있습니다. 그러나 R 객체 조작에 대한 많은 경험이 없으므로 (그리고 R, 일반적으로 그 문제에 관해서) 한 번 해보고 의견을 말하십시오. –