1

I'm preprocessing some data from sensor-created files into the format required for external analysis (ultimately, it needs to be output as a CSV). The end goal is something like this:

1   C3  C4  Cz  Pz  AllSites    2   C3  C4  Cz  Pz  AllSites    3   C3  C4  Cz  Pz  AllSites
50:23.9 0   0   0   0   0       53:15.0 0   0   0   0   0       09:15.0 0   0   0   0   0
50:24.9 1   0   0   1   0       53:16.0 1   0   0   1   0       09:16.1 0   0   1   0   0
50:26.0 1   0   0   0   0       53:17.1 1   0   0   1   0       09:17.1 0   0   1   0   0
50:27.0 1   0   0   1   0       53:18.1 1   1   1   0   0       09:18.1 0   0   1   1   0
50:28.0 0   1   0   0   0       53:19.2 1   0   0   0   0       09:19.2 0   0   1   0   0
50:29.1 1   1   1   1   1       53:20.2 1   0   0   1   0       09:20.2 0   0   1   0   0
50:30.2 0   1   1   0   0       53:21.2 1   0   0   0   0       09:21.2 0   0   0   1   0
50:31.2 0   0   0   0   0       53:22.3 0   0   0   0   0       09:22.3 0   0   0   1   0

Each set of columns is data from one session. The only catch is that sessions are of inequal length (and thus each group has a different number of observations), so at the moment, it's all in a list instead of a data frame. I have found a few different ways of exporting to CSV (e.g., this question), but they all involve converting to a data frame first. How do I export a list to CSV without converting it to a data frame first?

N.B.: I also found a bunch of questions about exporting a list of data frames to a series of CSV files, but for this application, all the data frames need to be in a single CSV.

Community
  • 1
  • 1
Krysta
  • 220
  • 3
  • 11

3 Answers3

2

Lets make some simple samples:

b1 = data.frame(C3=sample(c(0,1),8,TRUE),C4=sample(c(0,1),8,TRUE),Cz=sample(c(0,1),8,TRUE))
b2 = data.frame(C3=sample(c(0,1),3,TRUE),C4=sample(c(0,1),3,TRUE),Cz=sample(c(0,1),3,TRUE))
b3 = data.frame(C3=sample(c(0,1),8,TRUE),C4=sample(c(0,1),8,TRUE),Cz=sample(c(0,1),8,TRUE))

You cant just column-bind them and hope R pads out the smaller columns:

> cbind(b1,b2,b3)
Error in data.frame(..., check.names = FALSE) : 
  arguments imply differing number of rows: 8, 3

So we need to paste them into a big enough data frame. Lets make one full of NAs to start:

b = data.frame(matrix(NA, ncol=ncol(b1)+ncol(b2)+ncol(b3), nrow=max(nrow(b1),nrow(b2),nrow(b3))))
dim(b)
[1] 8 9

Then this code puts each b data frame in the right place. Each one is a bit further along:

> b[1:nrow(b1),1:ncol(b1)]=b1
> b[1:nrow(b2),(1:ncol(b1))+ncol(b1)]=b2
> b[1:nrow(b3),(1:ncol(b1))+ncol(b1)+ncol(b2)]=b3
> b
  X1 X2 X3 X4 X5 X6 X7 X8 X9
1  1  1  1  1  0  0  0  0  1
2  1  1  0  0  0  0  0  1  0
3  0  0  1  0  1  1  0  1  1
4  1  1  1 NA NA NA  1  1  1
5  0  0  0 NA NA NA  0  0  0
6  0  1  0 NA NA NA  1  0  1
7  0  0  0 NA NA NA  1  1  1
8  0  1  0 NA NA NA  1  1  1

Easy enough to generalise in a loop over a list. Now:

> write.csv(b,na="")
"","X1","X2","X3","X4","X5","X6","X7","X8","X9"
"1",1,1,1,1,0,0,0,0,1
"2",1,1,0,0,0,0,0,1,0
"3",0,0,1,0,1,1,0,1,1
"4",1,1,1,,,,1,1,1
"5",0,0,0,,,,0,0,0
"6",0,1,0,,,,1,0,1
"7",0,0,0,,,,1,1,1
"8",0,1,0,,,,1,1,1

Gives us those empty columns. You probably need to fiddle about to get the column headers back and repeated but that's easy enough...

Spacedman
  • 92,590
  • 12
  • 140
  • 224
0

Not sure if this is what you need... but it's a shot...

a <- data.frame(small=letters)
b <- data.frame(big=LETTERS)
l <- list(a=a, b=b)

sapply(names(l), function(x)write.csv(l[[x]], file=paste0(x, ".csv")))

# or maybe all in the same file...
sapply(names(l), function(x)write.table(l[[x]], file="c.csv", append=T))
cory
  • 6,529
  • 3
  • 21
  • 41
0

A csv file is most often used to export data in tabular form. They map perfectly with the data.frame R objects. list objects are way more general and exhibit a lot of flexibility that a simple csv format cannot handle in many cases.

In your cases sure you have a list, but the components of your list are data frames that share (apparently) the same structure (same number and names of the columns). So, it's pretty trivial to join all them in just one data frame. You only need an additional column that indicates the session. So, if mylist is your list, you can try:

    mydf<-do.call(rbind,mylist)
    elLength<-vapply(mylist,length,1)
    mydf$Session<-rep(1:length(mylist),times=elLength))

In this way you end up with a single data frame and you can extract the session through the Session column. You can use read.csv to export it to a csv file.

nicola
  • 24,005
  • 3
  • 35
  • 56
  • No, that gives a different format from above (which is different from what the further analysis needs, so not useful). – Krysta Sep 18 '14 at 13:15