costebk08 costebk08 - 1 month ago 6
R Question

Dynamically write text files from larger data-frame in R

I have a data-frame which looks something like this:

df<-rbind(c(1,0,1,0,1,NA),c(1,0,0,1,1,NA),c(1,0,0,0,0,NA),c(1,1,1,1,1,NA),c( 2,0,1,1,1,1),c(2,1,1,0,0,0),c(2,0,0,0,0,1),c(2,1,1,1,1,1),c(2,0,0,0,0,0))
colnames(df)<-c("Team","A","B","C","D","E")
print(df)

Team A B C D E
1 0 1 0 1 NA
1 0 0 1 1 NA
1 0 0 0 0 NA
1 1 1 1 1 NA
2 0 1 1 1 1
2 1 1 0 0 0
2 0 0 0 0 1
2 1 1 1 1 1
2 0 0 0 0 0


I would like to dynamically write each team result as a text file where the name of each file corresponds to the team number and is written without the NAs (each file only contains its respective 0s and 1s. Such that the final result looks like

"1.txt"
0 1 0 1
0 0 1 1
0 0 0 0
1 1 1 1
"2.txt"
0 1 1 1 1
1 1 0 0 0
0 0 0 0 1
1 1 1 1 1
0 0 0 0 0


Thank you!

Answer

The by function is good for this, it splits a data.frame by factor level and applies a function to each group (see ?by).

In your case you could use something like:

by(df, df$Team, function(x)
  write.table(x, sep = "\t", file = paste0(unique(x$Team), ".txt")))

Expanded based on comment:

by(df, df$Team, function(x){

  # drop columns if all are NA
  subset <- x[,colSums(is.na(x)) < nrow(x)]

  # drop team column and write groups to individual files
  write.table(subset[,-1], sep = "\t", 
    file = paste0(unique(x$Team), ".txt"),
    col.names = FALSE, row.names = FALSE)

  })