Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write files with Unix end of lines on R for Windows

Tags:

r

I have an R script that creates a text file on Windows.

I use both write.table and write functions to write to the file.

I then need to use this file on Unix systems, but the file has Windows end of line characters (^M).

Is it possible to write files with R on Windows that have Unix end of line characters?

Edit

Here is a reproducible example:

output.file <- file.path("./test.txt")

x <- c(1,2,3,4)
y <- c(5,6,7,8)
my.df <- data.frame(x, y)
my.df[] <- lapply(my.df, sprintf, fmt = "%14.7E")

write("First line", file = output.file)
write("Second line", file = output.file, append = TRUE)
write.table(my.df,
            row.names = FALSE,
            col.names = FALSE,
            file = output.file,
            quote = FALSE,
            append = TRUE,
            sep = "")

And the result, as seen by NotePad++:

enter image description here

like image 328
Ben Avatar asked Apr 29 '16 08:04

Ben


People also ask

Can Windows use Unix line endings?

Starting with the current Windows 10 Insider build, Notepad will support Unix/Linux line endings (LF), Macintosh line endings (CR), and Windows Line endings (CRLF) as usual.

How do I change Unix line endings in Windows?

Converting using Notepad++ To write your file in this way, while you have the file open, go to the Edit menu, select the "EOL Conversion" submenu, and from the options that come up select "UNIX/OSX Format". The next time you save the file, its line endings will, all going well, be saved with UNIX-style line endings.

Why do Windows and Unix use different line endings in text files?

Unix followed the Multics practice, and later Unix-like systems followed Unix. This created conflicts between Windows and Unix-like OSes, whereby files composed on one OS cannot be properly formatted or interpreted by another OS (for example a UNIX shell script written in a Windows text editor like Notepad).

What line endings does Windows use?

Back to line endings The reasons don't matter: Windows chose the CR/LF model, while Linux uses the \n model. So, when you create a file on one system and use it on the other, hilarity ensues.


2 Answers

As stated in help(write.table):

To write a Unix-style file on Windows, use a binary connection e.g. file = file("filename", "wb").

In your example, just change first line to open a "wb" connection and close file at the end:

output.file <- file("./test.txt", "wb")

x <- c(1,2,3,4)
y <- c(5,6,7,8)
my.df <- data.frame(x, y)
my.df[] <- lapply(my.df, sprintf, fmt = "%14.7E")

write("First line", file = output.file)
write("Second line", file = output.file, append = TRUE)
write.table(my.df,
            row.names = FALSE,
            col.names = FALSE,
            file = output.file,
            quote = FALSE,
            append = TRUE,
            sep = "")

close(output.file)

enter image description here

like image 126
HubertL Avatar answered Oct 03 '22 19:10

HubertL


unix type line endings can be achieved by using wb write|binary mode in file connections.

This quote from Rnews article may be helpful: Ripley, B. D. (2001) Connections. R News, 1/1, 16–7.

Text vs binary There is a distinction between text mode and binary mode connections. The intention is that text-based functions like scan and cat should use text mode connections, and binary mode is used with readBin and writeBin. This distinction is not yet consistently enforced, and the main underlying difference is whether files are opened in text or binary mode (where that matters). It now looks as if opening all files in binary mode and managing the translation of line endings internally in R will lead to fewer surprises. Already reading from a connection in text mode translates lines endings from Unix (LF), DOS/Windows (CRLF) and Macintosh (CR) formats (and from all connections, not just files).

# setup file connection
con <- file( output.file )

# open connection
if( !isOpen(con = con, rw = "wb") ) { open( con, open = "wb" ) }

# write contents
write( x = paste( colnames(my.df), collapse = "\t" ), file = con )
for( i in 1:nrow( my.df )){
  write(paste( my.df[i, ], collapse = "\t" ), file = con )
}
close( con )  # close and destroy a connection

# verify file contents
read.table(output.file, header = TRUE, sep = "\t")
#   x y
# 1 1 5
# 2 2 6
# 3 3 7
# 4 4 8
like image 36
Sathish Avatar answered Oct 03 '22 19:10

Sathish