0

I want to create a data set using the following code, the aim is to add a blank row between each group, and three blank rows between each treatment. I wish it looks as the following dataset.

value group treatment
 39.7     A         1
 53.5     A         1
 51.1     A         1
 67.8     A         1

 84.8     B         1
 80.3     B         1
 79.6     B         1
 84.3     B         1



 31.0     C         2
 32.0     C         2
 33.0     C         2
 34.0     C         2

  1.0     D         2
  2.0     D         2
  3.0     D         2
  4.0     D         2

I wrote down a double for loop but it doesn't work well. I can't figure it out. Can anyone tell me what is the problem with it?

mydata <- data.frame(value=c(39.7,53.5,51.1,67.8,84.8,80.3,79.6,84.3,31,32,33,34,1,2,3,4),group=c("A","A","A","A","B","B","B","B","C","C","C","C","D","D","D","D"),treatment=c(1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2))

blank <- data.frame(value=NA,group="NA",treatment=NA)
blank1 <- data.frame(value=c(NA,NA,NA),group=c("NA","NA","NA"),treatment=c(NA,NA,NA))

uni<-unique(mydata$treatment)
b<-length(uni)
out <- c()
out1<-c()

for (i in 1:b) {
  emp<-subset(mydata,treatment==uni[i])
  uni1<-unique(emp$group)
  c<-length(uni1)
  for (j in 1:c){
    emp1<-subset(subset(mydata,treatment==uni[i]),group==uni1[j])
    stack<-rbind(emp1,blank)
    out<-rbind(stack,out)
  }
  stack1<-rbind(out,blank1)
  out1<-rbind(stack1,out1)
}
fruit J
  • 25
  • 1
  • 4
  • You actually want blank observations or is this just about printing it? – Frank May 15 '15 at 01:45
  • Oh, just looked at your code. It would be less messy to re-use `emp` rather than have your nested `subset`. Also, you are adding four blank rows, not three (since you already have a blank from the inner row). Finally, you need to initialize `out` inside the first loop -- it needs to be blank for each new `treatment`. – Frank May 15 '15 at 02:19
  • 1
    Hi Frank, Thanks so much for the response. You are correct, I did this for printing the tables. Your suggestion of 'initialize out inside the first loop' is amazing, it solved my problem!!! Wow~~I have been struggling with this for a long time.....thanks a lot!! – fruit J May 15 '15 at 14:42
  • No problem; glad you've solved it :) – Frank May 15 '15 at 14:51

1 Answers1

1

I can't imagine a practical reason for having data with blank rows in such a pattern, so I'm assuming it is simply for printing:

printables <- lapply(
  split(mydata,mydata$treatment),
  function(t)
    split(t,as.character(t$group)))

for (t in seq_along(printables)){
  for(g in seq_along(printables[[t]])){
    print(printables[[t]][[g]],row.names=FALSE)
    cat('\n')
  }
  cat('\n\n')
}
Frank
  • 66,179
  • 8
  • 96
  • 180
  • Hi Frank, could you also tell me how to output this 'printables' to a txt file or csv file? Thanks a lot!!~~ – fruit J May 15 '15 at 15:32
  • `sink("myfile.txt")` before the loop and `sink()` after. For csv, if your loop above works, you can use `write.csv(out1,file="mycsvfile.csv")` – Frank May 15 '15 at 16:02
  • another more.....sorry for so many questions....sink() can't deal with the NA, right? can anything help to make thye 'NA' shown as blank in txt file? So appreciate!!! – fruit J May 15 '15 at 18:32
  • @fruitJ I'm not sure. You may need to adjust your data so that everything (even numbers) is converted to character/string; substitute an empty string for the NAs; and then print, as described here: http://stackoverflow.com/questions/19592706/setting-na-to-blank – Frank May 15 '15 at 18:41
  • 1
    It is awesome!! It works!! many many many thanks~~~ Flowers!@Frank – fruit J May 15 '15 at 19:08