1

It seems pretty clear that R strings can't have nul characters. (ref: https://stat.ethz.ch/R-manual/R-devel/library/base/html/Quotes.html). Problem is, I need to output some nuls to a file. Below is what I wrote when I didn't know I had a problem, and it works file when my mismatched value is any other character.

The purpose of the code is to take a 2d matrix and output a 1d character string where hits are labelled with hex 80 and mismatches are hex 0 (nul). If R doesn't allow strings to contain NUL, what is the "R" way to do this?

mat<-matrix(c(0,0,0, 0,0,0, 1,0,0),nrow=3,ncol=3)
PrintCellsWhere<-function(mymat=matrix(),value=-1) {
  outputstring<-""
  for(j in 1:ncol(mymat)) {
    for(i in 1:nrow(mymat)) {
      if(mymat[i,j]==value) {
        outputstring<-paste0(outputstring,"\x80")
      } else{
          outputstring<-paste0(outputstring,"\x00")
      }
    }
  }
  return(outputstring)
}
PrintCellsWhere(mymat=mat,value=1)

Error message reported : Error: nul character not allowed

The end goal is to output to a file this data construct with nuls in it. I thought I was going to use writeLines...

(Added a better code example)

chrysrobyn
  • 73
  • 1
  • 10
  • It's easier to help you if you include a simple [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. What's a specific input to this function that can be used for testing. You can't have nuls in characters, but you can create raw vectors in R which contain bytes with a value of 0. – MrFlick Mar 05 '19 at 15:15
  • I've added a matrix definition to help explain my problem. I thought I wanted to prepare a big string and use writeLines to output it, but seems like that won't work with nuls. Is there a good way to write a nul to a file in R? – chrysrobyn Mar 05 '19 at 15:25

1 Answers1

1

You can't have nuls in strings, but you can have a raw vector that has a 0 byte. For example you could change your function to

PrintCellsWhere<-function(mymat=matrix(), value=-1) {
    as.raw(ifelse(mymat==value, 128,0))
}

Note the double loop is not necessary at all in R. This will return a "raw" byte vector in R. You can write that to a file with something like

writeBin(PrintCellsWhere(mat, 1), "test.bin")
MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • 1) Thanks for fixing the function to a more R styled iteration through the matrix. 2) I'm going to take a bit to work the writeBin into my code. First pass it didn't write NULs right, so need to debug a bit i think. – chrysrobyn Mar 05 '19 at 15:54
  • What exactly do you mean that it didn't write the NULs right? How exactly did you check the result? – MrFlick Mar 05 '19 at 15:56
  • Later in my code, I put a preface ascii string on before writing the file out. Using paste0 for that really didn't like the raw vector that gets returned by the as.raw. How would you recommend a header to the data when using writeBin? – chrysrobyn Mar 05 '19 at 16:21
  • Use a connection rather than a literal file name so you can make multiple calls to `writeBin`, one with your string and one with the bytes. Or convert your string to bytes with `charToRaw()` and append it in with `c()` rather than `paste()` it – MrFlick Mar 05 '19 at 16:24