복붙노트

[HADOOP] R : 직렬화 된 개체에서 CSV 만들기

HADOOP

R : 직렬화 된 개체에서 CSV 만들기

목록을 가져와 각 항목을 serialize하고 키 / 값 쌍이있는 텍스트 파일을 만드는 키가있는 CSV 파일에 저장하려고합니다. 궁극적으로 이것은 Hadoop 스트리밍을 통해 실행될 것이므로 물어보기 전에 실제로 텍스트 파일에 있어야한다고 생각합니다. (하지만 나는 다른 아이디어에 대해 개방적이다.)이 모든 것은 처음에는 꽤 똑바로 보였다. 하지만 직렬화를 통해 원하는대로 작동시킬 수는 없습니다.

내가 이렇게하면 :

> rawToChar(serialize("blah", NULL, ascii=T))
[1] "A\n2\n133888\n131840\n16\n1\n9\n4\nblah\n"

그럼 나는 그 성가신 \ n 내 CSV 파싱 나중에 망쳐있다. 들어가서 \ n을 다른 문자열로 바꿀 수 있습니다. 그러나 이것은 약간 지저분 해 보입니다.

또 다른 옵션은 rawToChar () 호출을 생략하고 원시 ascii를 텍스트 파일로 펌핑하는 것입니다.

> serialize("blah", NULL, ascii=T)
 [1] 41 0a 32 0a 31 33 33 38 38 38 0a 31 33 31 38 34 30 0a 31 36 0a 31 0a 39 0a
[26] 34 0a 62 6c 61 68 0a

음, 그냥 텍스트 파일에 덤프하면 목록의 각 요소 뒤에 \ n 표시됩니다. 그래서 조금 붙여 넣기 / 접기를 시도했습니다.

> ser <- serialize("blah", NULL, ascii=T)
> ser2 <- paste(ser, collapse="")
> ser2
[1] "410a320a3133333838380a3133313834300a31360a310a390a340a626c61680a"

이제 이것이 CSV 텍스트 파일에 쓸 수있는 가치입니다! 단지 ... 어떻게 다시 원시로 다시 되돌릴 수 있습니까? 첫 번째 16 진수 요소를 취해 봅시다. 41 원시 항목 목록을 작성하고 16 진수 값 41을 요소 중 하나에 밀어 넣는 방법을 알아낼 수조차 없습니다. 원시 16 진수 값을 원시 목록으로 밀어 넣으려고하면 다음과 같이 끝납니다.

> r <- raw(1)
> r[1] <- 41
Error in r[1] <- 41 : 
  incompatible types (from double to raw) in subassignment type fix
> r[1] <- as.raw(41)
> r[1]
[1] 29 

쓰레기! 29! = 41 (29의 정말로 큰 값과 41의 정말로 작은 값을 제외하고)

이 너트를 깨는 방법에 대한 아이디어가 있습니까?

해결법

  1. ==============================

    1.caTools 패키지에는 사용할 수있는 Base64 인코더 - 디코더가 있습니다.

    caTools 패키지에는 사용할 수있는 Base64 인코더 - 디코더가 있습니다.

    > library(caTools)
    > s<-base64encode(serialize("blah",NULL))
    > s
    [1] "WAoAAAACAAIKAQACAwAAAAAQAAAAAQAAAAkAAAAEYmxhaA=="
    > unserialize(base64decode(s,"raw"))
    [1] "blah"
    
  2. ==============================

    2.그의 위대한 대답은 jmoy에게 감사드립니다. 나는 그의 추천을 사용했고 그것은 훌륭하게 작동합니다. 장래의 히치하이커를 위해 필자는 목록을 직렬화 된 CSV 텍스트 파일로 변환 한 다음 다시 목록으로 변환하는 기능을 남겨두고 있습니다. 이 게시물을 커뮤니티 위키로 표시하고 있습니다. 다음을 수행하는 더 깨끗한 방법이 있으면 언제든지 편집 할 수 있습니다.

    그의 위대한 대답은 jmoy에게 감사드립니다. 나는 그의 추천을 사용했고 그것은 훌륭하게 작동합니다. 장래의 히치하이커를 위해 필자는 목록을 직렬화 된 CSV 텍스트 파일로 변환 한 다음 다시 목록으로 변환하는 기능을 남겨두고 있습니다. 이 게시물을 커뮤니티 위키로 표시하고 있습니다. 다음을 수행하는 더 깨끗한 방법이 있으면 언제든지 편집 할 수 있습니다.

    listToCsv <- function(inList, outFileName){
      require(caTools)
      if (is.list(inList) == F) 
            stop("listToCsv: The input list fails the is.list() check.")
      fileName <- outFileName
      cat("", file=fileName, append=F)
    
      i <- 1
      for (item in inList) {
        myLine <- paste(i, ",", base64encode(serialize(item, NULL, ascii=T)), "\n", sep="")
        cat(myLine, file=fileName, append=T) 
        i <- i+1
      }
    }
    
    csvToList <- function(inFileName){
      require(caTools)
      linesIn <- readLines(fileName, n=-1)
      outList <- NULL
    
      i <- 1
      for (line in linesIn){
        outList[[i]] <- unserialize(base64decode(strsplit(linesIn[[i]], split=",")[[1]][[2]], "raw"))
        i <- i+1
      }
      return(outList)
    }
    
  3. ==============================

    3.어쩌면 as.raw (65) 대신 65 (십진수)가 41 (16 진수)

    어쩌면 as.raw (65) 대신 65 (십진수)가 41 (16 진수)

     > as.hexmode(65)
    [1] "41"
    

    인코딩의 경우 Hadoop 스트리밍 내에서 바이너리 데이터로 작업 할 수 있습니까?

  4. from https://stackoverflow.com/questions/3114043/r-creating-a-csv-out-of-serialized-objects by cc-by-sa and MIT license