【问题标题】:How to read a CSV file that includes vectors of different lengths separated by commas?如何读取包含用逗号分隔的不同长度向量的 CSV 文件?
【发布时间】:2013-11-04 04:43:00
【问题描述】:

假设您有一个 CSV 文件。文件的每一行都有数字、向量和日期。每个向量的元素用分号分隔。例如,这个 csv 文件中的向量 y 看起来像“;1;2;4;7;2”。向量的长度不同。我无法使用

读取此文件
read.table() 

read.csv()

即使尝试一些类似于这里写的东西How to read a .csv file containing apostrophes into 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

每一行都有相同数量的',',行之间唯一的主要区别是向量可以不同。请注意,有时字段可能为空白。我认为以列表的列表形式输出是最有意义的。我正在考虑编写我自己的函数,它实际上看起来像(我对列表还不是很精通,所以我的语言可能离这里很远)

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) 的第一个条目。所以也许请记住这一点。另请注意,可以选择让此文件使用除分号之外的其他字符来分隔向量。

【问题讨论】:

    标签: r csv


    【解决方案1】:

    仍然不知道您在寻找什么,这里有一个建议。

    从 G. Grothendieck 的回答开始 DF:

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

    我会从我的“splitstackshape”包中建议concat.split.multiple,因为(1)您可以一次拆分多个列; (2) 每列可以有不同的分隔符; (3) 您可以选择拆分数据的“宽”或“长”表示。可以使用“reshape2”包中的meltdcast 等工具进一步处理长格式,让您在以后做其他事情时有很大的灵活性。

    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
    

    【讨论】:

      【解决方案2】:

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

      添加:如何展平。

      【讨论】:

        猜你喜欢
        • 2015-03-19
        • 2020-03-20
        • 2021-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多