2011-07-01 2 views
9

RDATA 파일에서 개체를 나열하고 전체 개체 집합이 아닌 선택한 개체 만로드하는 데 관심이 있습니다 (일부 개체가 크거나 환경에 이미있을 수있는 경우). attach()이 잘 작동하지 않기 때문에 이름에 충돌이있을 때이를 수행하는 방법에 대해서는 분명하지 않습니다. 를로드하지 않고 R 데이터 파일의 내용을 검사의 경우 :새로운 환경에 연결하여 .rdata 파일의 내용을 검사 할 수 있습니까?

1, 제공하는 솔루션은이 질문은 비슷하지만이 경우 listing contents of an R data file without loading

에 물었다 것과 다른했다 :

attach(filename) 
ls(pos = 2) 
detach() 
파일의 객체 및 글로벌 환경에서 그 사이에 이름 충돌이있는 경우

이 경고가 나타납니다 The following object(s) are masked _by_ '.GlobalEnv':

나는 새로운 환경을 만드는 시도,하지만 난 그것에 붙이는 것 같지 않습니다. 는 예를 들어,이 같은 오류가 발생합니다 :

lsfile <- function(filename){ 
    tmpEnv <- new.env() 
    evalq(attach(filename), envir = tmpEnv) 
    tmpls <- ls(pos = 2) 
    detach() 
    return(tmpls) 
} 
lsfile(filename) 

어쩌면 내가 evalq (또는 eval) 물건의 혼란을했습니다. 명명 충돌을 피할 수있는 다른 방법이 있습니까?

2 : 개체에 액세스하려는 경우 명명 충돌이없는 경우 .rdat 파일에서 작업하거나 새 개체로 복사 할 수 있습니다. 충돌이있는 경우 파일의 네임 스페이스에있는 객체에 어떻게 액세스합니까?

예를 들어 내 파일이 "sample.rdat"이고 객체가 surveyData이고 surveyData 객체가 이미 전역 환경에있는 경우 file:sample.rdat 네임 스페이스의 객체에 액세스하려면 어떻게해야합니까?

현재 모든 것을 임시 환경에로드 한 다음 필요한 것을 복사하여이 문제를 해결하지만 비효율적입니다.

+1

요청이 r-devel에 올라와있는 것을 보았습니다. 전체 .Rdta 파일을로드하는 대신에 사용할 수있는 것 같습니다. –

답변

4

attach을 호출 할 때 warn.conflicts=FALSE을 설정하여 경고를 표시하지 않을 수 있습니다. 개체가 전역 환경에서 마스크 된 경우 get을 사용하여 연결된 데이터에서 개체를 검색 할 수 있습니다.

x <- 1:10 
save(x, file="x.rData") 
#attach("x.rData", pos=2, warn.conflicts=FALSE) 
attach("x.rData", pos=2) 
(x <- 1) 
# [1] 1 
(x <- get("x", pos=2)) 
# [1] 1 2 3 4 5 6 7 8 9 10 
+0

@SimonUrbanek의 답변 아래에 남겨진 주석에 따라,'attach()'가'load()'를 호출하지 않는다고 생각하는 것 같습니다. 그 오류는 검사 부족 ('Rprof()'로 인해 ...)과 초고속 로딩 시간 (아마도 디스크 캐싱으로 인한) 때문이었습니다. 그래도 내 질문의 두 번째 부분에 대한 답변입니다. 시몬 (Simon)이 ​​지적한 것처럼 사용 기준별로로드하는 것을 피하는 유일한 방법은 지연로드 형식으로 한 번 변환하는 것입니다. – Iterator

5

난 그냥 사용 env= 인수 load()에 :

> x <- 1; y <- 2; z <- "foo" 
> save(x, y, z, file="/tmp/foo.RData") 
> ne <- new.env() 
> load(file="/tmp/foo.RData", env=ne) 
> ls(env=ne) 
[1] "x" "y" "z" 
> ne$z 
[1] "foo" 
> 
이 방법의 비용이 전체 RData에 파일을 참조 할 수 --- 그러나 다른 한편으로는 어쩔 수없는 것 같다이다

어쨌든 다른 방법으로 그러한 파일의 '내용'목록을 제공하는 것 같지 않습니다.

+0

환경 혼란을 싫어하면 관심있는 내용을 글로벌 env에 복사하면 새로운 환경을 파괴하기 위해'rm (ne)'을 사용할 수 있습니다. –

2

@Dirk 및 @Joshua에게 감사드립니다.

나는 주현절을 가지고있었습니다. SMP 또는 MC를 사용하는 foreach 명령/패키지는 글로벌 환경 만 상속하지만 환경과 충돌하지는 않는 환경을 생성하는 것으로 보입니다.

lsfile <- function(list_files){ 
    aggregate_ls = foreach(ix = 1:length(list_files)) %dopar% { 
     attach(list_files[ix]) 
     tmpls <- ls(pos = 2) 
     return(tmpls) 
    } 
    return(aggregate_ls) 
} 

lsfile("f1.rdat") 
lsfile(dir(pattern = "*rdat")) 

이 기능은 현재 병렬 처리가 가능하므로 유용합니다. 이 버전은 베어 본 버전이며 더 자세한 정보를 제공하기 위해 수정 하겠지만 지금까지는 무시하지 않고도 충돌을 피할 수있는 유일한 방법 인 것 같습니다.

따라서 질문 1은 경고를 무시하거나 (@ Joshua가 제안한대로) 또는 어떤 마법을 사용하여 해결할 수 있습니다 foreach 소환.

2 부에서는 대상을 로딩 할 때 @Joshua가 올바른 아이디어를 가지고 있다고 생각합니다. "get"이 할 것입니다.

foreach 마법은 .noexport 옵션을 사용하여 작동 할 수도 있습니다. 그러나 명확히 제외되지 않은 것은 무엇이든 지구 환경으로부터 상속/수출 될 것입니다 (ls() 할 수는 있지만 항상 첨부 된 데이터 세트의 가능성이 있습니다). 안전을 위해 명명 충돌의 위험을 피하기 위해 get()을 계속 사용해야 함을 의미합니다. 하위 환경으로로드하면 명명 충돌을 피할 수 있지만 불필요한 객체가로드되는 것을 방지하지는 못합니다.

@ Joshua의 대답은 내 foreach 우회보다 훨씬 간단합니다.

16

이 질문은의이 두 가지를 명확하게 언급되어 있기 때문에 그래서 load

  • 대신에 그것을 사용 아무 소용이 당신에 대한 선택적 접근을하려면 정말 없다

    1. attach() 단순히 load() 호출을 마스킹을 방지하면 단순히 파일을 새로운 환경으로로드하는 것이 훨씬 쉽습니다.

      e = local({load("foo.RData"); environment()}) 
      

      ls(e)을 사용하고 e$x과 같은 내용에 액세스 할 수 있습니다. 검색 경로에 실제로 사용하려면 attach을 계속 사용할 수 있습니다.

    FWIW으로 .rdata 파일 인덱스를 (개체가 하나의 큰 pairlist에 저장된다)이 없다, 그래서 당신은로드하지 않고 포함 된 개체를 나열 할 수 없습니다. 편리하게 액세스하려면 lage-load 형식으로 변환하여 각 객체를 따로 따로로드 할 수 있도록 색인을 추가하십시오 (Get specific object from Rdata file 참조)

  • +0

    먼저, 당신을 환영하는 코러스에 참여합시다! 둘째,'attach()'가'load()'를 호출한다는 사실은 나에게 놀라운 일이다. 한가지 목표는'attach()'를 사용하는 것이었지만 다른 대답을 받아 들였을 때 나는'attach()'가 실제보다 빠르다고 생각했던 테스트 케이스를 가지고 있었다. 'load()'. OTOH, 나는 이제 내가 디스크 캐싱에 잘못 인도되었을지도 모른다는 것을 알고 있습니다. 저주. 무슨 일이 일어 났는지 보려면 테스트 사례를 다시 방문해야 할 것입니다. – Iterator

    +0

    안녕하세요, 고마워요. 나는 SO에 관한 잘못된 정보로 연결되는 링크를 보았습니다. (나는이 게시물을 의미하지는 않습니다. Re'attach', 나는 속도를 검사하지 않았고, 단지 현재의 R 코드를 보았다 : P –

    관련 문제