![](/img/trans.png)
[英]How to put elements of a list of vectors of different lengths into a data frame, with elements of vectors being separated as different columns
[英]How to read a CSV file that includes vectors of different lengths separated by commas?
假設您有一個CSV文件。 文件的每一行都有數字,向量和日期。 每個向量的元素由分號分隔。 例如,此csv文件中的向量y看起來像“; 1; 2; 4; 7; 2”。 矢量是不同的長度。 我無法使用讀取此文件
read.table()
要么
read.csv()
即使嘗試了類似於此處所寫的內容如何將包含撇號的.csv文件讀入R? 。 下面是CSV文件中3行的簡化版本
1,6,;2;3.1;45;31.2;3,2,;1;1;1;1;1;5,10/22/1938 1:25
2,5,;1;22;12;1.4;66,7,;2;3;4;5;6;7;8;6;9,11/25/1938 1:25
3,1,;1;2;3;4;5;6;7;8;9,3.2,;1;2;3;4;5;6;7;9;10;11,11/25/1958 1:25
這里是逗號之間的空格,以使其更具可讀性
1, 6, ;2;3.1;45;31.2;3, 2, ;1;1;1;1;1;5, 10/22/1938 1:25
2, 5, ;1;22;12;1.4;66, 7, ;2;3;4;5;6;7;8;6;9, 11/25/1938 1:25
3, 1, ;1;2;3;4;5;6;7;8;9, 3.2, ;1;2;3;4;5;6;7;9;10;11, 11/25/1958 1:25
每行具有相同數量的','s,行之間唯一的主要區別是矢量可以不同。 請注意,有時字段可能為空。 我認為輸出以列表列表的形式最有意義。 我正在考慮編寫我自己的函數,它實際上看起來像(我不是很精通列表,所以我的語言可能會離這里)
data <- empty list of a list
while (we haven't reached the end of the file){ #don't know the function to do this
temp = get first line of file #don't know the function to do this
if temp is not empty{ #don't know the function to do this
indices = which(temp==',')
indices.col = which(temp==';')
put temp[1:(indices(1)-1)] in the (counter,1) location of data;
put temp[(indices(1)+1):(indices(2)-1)] in the (counter,2) location of data;
store the vector and deal with the colons somehow in (counter,3) location of data;
}
}
是否有更簡單的方法來執行此操作,可能以我錯過的方式使用read.table。 我沒有開始使用列表列表來執行此操作。 我想基本上對形式y = mx + b進行一些回歸分析,其中x是數值條目之一,y是應用於其中一個向量條目的函數的標量輸出(例如sum(vector)= a *行+ b)的第一個條目。 所以也許記住這一點。 另請注意,可以選擇讓此文件使用除半冒號之外的其他字符來分隔矢量。
使用read.csv
讀取它。 然后可以重新讀取第3列和第5列,為每個矩陣創建一個矩陣,並用這些矩陣替換它們的列,即第3列成為矩陣,第5列也是如此,如str
輸出所示:
Lines <- "1,6,;2;3.1;45;31.2;3,2,;1;1;1;1;1;5,10/22/1938 1:25
2,5,;1;22;12;1.4;66,7,;2;3;4;5;6;7;8;6;9,11/25/1938 1:25
3,1,;1;2;3;4;5;6;7;8;9,3.2,;1;2;3;4;5;6;7;9;10;11,11/25/1958 1:25
"
DF <- read.csv(text = Lines, header = FALSE, as.is = TRUE)
DF2 <- transform(DF,
V3 = as.matrix(read.table(text = V3, sep = ";", fill = TRUE)),
V5 = as.matrix(read.table(text = V5, sep = ";", fill = TRUE))
)
str
輸出。 請注意,第3列和第5列本身都是一個矩陣:
> str(DF2)
'data.frame': 3 obs. of 6 variables:
$ V1: int 1 2 3
$ V2: int 6 5 1
$ V3: num [1:3, 1:10] NA NA NA 2 1 1 3.1 22 2 45 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : NULL
.. ..$ : chr "V1" "V2" "V3" "V4" ...
$ V4: num 2 7 3.2
$ V5: int [1:3, 1:11] NA NA NA 1 2 1 1 3 2 1 ...
..- attr(*, "dimnames")=List of 2
.. ..$ : NULL
.. ..$ : chr "V1" "V2" "V3" "V4" ...
$ V6: chr "10/22/1938 1:25" "11/25/1938 1:25" "11/25/1958 1:25"
另請注意,如果您想要展平它,請嘗試:
DF.flat <- do.call(data.frame, DF2)
增加:如何變平。
仍然不確切知道你在尋找什么,這是一個建議。
從G.Grothendieck的答案開始:
### Optional cleanup to remove the leading semicolon.
### Not doing so will result in a couple of empty columns.
DF$V3 <- gsub("^;", "", DF$V3)
DF$V5 <- gsub("^;", "", DF$V5)
我建議concat.split.multiple
從我的“splitstackshape”包,因為(1)你可以一次分裂多列; (2)每列可以有不同的分隔符; (3)您可以選擇分割數據的“寬”或“長”表示。 長形式可以使用“reshape2”軟件包中的melt
和dcast
等工具進一步操作,為您以后做其他事情提供了很大的靈活性。
library(splitstackshape)
concat.split.multiple(DF, c("V3", "V5"), ";")
# V1 V2 V4 V6 V3_1 V3_2 V3_3 V3_4 V3_5 V3_6 V3_7 V3_8 V3_9 V5_1
# 1 1 6 2.0 10/22/1938 1:25 2 3.1 45 31.2 3 NA NA NA NA 1
# 2 2 5 7.0 11/25/1938 1:25 1 22.0 12 1.4 66 NA NA NA NA 2
# 3 3 1 3.2 11/25/1958 1:25 1 2.0 3 4.0 5 6 7 8 9 1
# V5_2 V5_3 V5_4 V5_5 V5_6 V5_7 V5_8 V5_9 V5_10
# 1 1 1 1 1 5 NA NA NA NA
# 2 3 4 5 6 7 8 6 9 NA
# 3 2 3 4 5 6 7 9 10 11
out <- concat.split.multiple(DF, c("V3", "V5"), ";", "long")
head(out)
# V1 V2 V4 V6 time V3 V5
# 1 1 6 2.0 10/22/1938 1:25 1 2 1
# 2 2 5 7.0 11/25/1938 1:25 1 1 2
# 3 3 1 3.2 11/25/1958 1:25 1 1 1
# 4 1 6 2.0 10/22/1938 1:25 2 NA NA
# 5 2 5 7.0 11/25/1938 1:25 2 NA NA
# 6 3 1 3.2 11/25/1958 1:25 2 NA 11
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.