Question

I am trying to write and append my output to a csv file using R. First, the program will write the header and then inside a for loop append the generated rows. An example code is as follows:

   writeLines(text=c('Mean','Sd','\n'),'file.csv',sep=',')
   for(i in 1:5)
    {x <- rnorm(10); dat1 <- cbind(mean(x),sd(x))
      write.table(dat1,'file.csv',append=TRUE,sep=',',col.names=FALSE)
    }

But this shifts my first row to right by one element giving the following in csv output. How can I avoid this? Is there another way to achieve what I am trying to do here?

EDIT Also, how do we remove the column labeling which is 1 in this case? col.names=FALSE does not seem to help. I used row.names=FALSE as suggested by @Roman Luštrik. It solved this problem. But the first row shifting problem is not yet to be addressed.

enter image description here

Was it helpful?

Solution

Why not use paste()?

writeLines(text=paste(c('Mean','Sd'),collapse=','),'file.csv',sep="\n")
for(i in 1:5) {
  x <- rnorm(10); dat1 <- cbind(mean(x),sd(x))
  write.table(dat1, 'file.csv', append=TRUE, sep=',', row.names=FALSE, col.names=FALSE)
}

OTHER TIPS

I've often had to write to files in such a manner. I usually do it this way.

If file already exists, just append without the column and row names. If not, create a brand new one.

x <- rnorm(10); dat1 <- data.frame(Mean = mean(x), Sd = sd(x))
if (file.exists("file.csv")) {
   write.table(dat1, file = "file.csv", append = TRUE, col.names = FALSE, row.names = FALSE, sep = ",")
} else {
   write.table(dat1, file = "file.csv", col.names = TRUE, row.names = FALSE, sep = ",")
}

To understand how the CSV file looks like, I suggest that you open it in a text editor and not in Excel (which transforms it). Because then you could see that your CSV starts like:

Mean,Sd,
,"1",0.441737369447746,1.07695222886305
[...]

...two too many commas.

In your writeLines statement, what you meant is the following:

   writeLines(paste('Mean','Sd',sep=","),'file.csv')

What is wrong in your case is that you replaced the default sep="\n" of writeLines with sep="," and apparently writeLines prints a separator also after the last item, unlike paste. (This makes much more sense when printing lines as the default operation, closing also the last line with a \n.)

In write.Table, use row.names=FALSE.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top