将不等长的数据导出为CSV

时间:2014-09-17 19:42:18

标签: r csv

我将传感器创建的文件中的一些数据预处理为外部分析所需的格式(最终,它需要以CSV格式输出)。最终目标是这样的:

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

每组列都是来自一个会话的数据。唯一的问题是会话长度不等(因此每个组的观察数量都不同),所以目前它们都在列表中而不是数据帧中。我找到了几种不同的导出方式(例如this question),但它们都涉及首先转换为数据帧。如何将列表导出到CSV而不先将其转换为数据框?

N.B。:我还发现了一系列关于将数据框列表导出到一系列CSV文件的问题,但对于这个应用程序,所有数据框都需要在一个CSV中。

3 个答案:

答案 0 :(得分:2)

让我们做一些简单的样本:

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))

你不能对它们进行列绑定,并希望R填充较小的列:

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

因此我们需要将它们粘贴到足够大的数据框中。让我们开始使用一个NAs:

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

然后,此代码将每个b数据框放在正确的位置。每一个都更进一步:

> 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

足够简单地在列表中循环。现在:

> 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

给我们那些空列。您可能需要摆弄以重新获得列标题并重复,但这很容易......

答案 1 :(得分:0)

不确定这是否是你需要的...但它是一个镜头......

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))

答案 2 :(得分:0)

csv文件最常用于以表格形式导出数据。它们与data.frame R对象完美映射。 list对象更通用,并且表现出很多灵活性,在许多情况下,简单的csv格式无法处理。

在您的情况下,确定您有一个列表,但列表的组件是共享(显然)相同结构的数据框(列的数量和名称相同)。因此,将它们加入到一个数据帧中是非常微不足道的。您只需要一个指示会话的附加列。因此,如果mylist是您的列表,您可以尝试:

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

通过这种方式,您最终得到一个数据框,您可以通过Session列提取会话。您可以使用read.csv将其导出到csv文件。