包含多个数据集/不同列数的CSV

时间:2017-05-09 14:50:47

标签: r csv dataframe s4

How can you read a CSV file in R with different number of columns类似,我有一些复杂的CSV文件。我的产品来自SAP BusinessObjects,其挑战与引用的问题不同。我想自动捕获一个CSV文件中保存的任意数量的数据集。有许多CSV文件,但让我们从其中一个文件开始。

给定:一个包含多个平面表的CSV文件。

通缉:几个数据帧或其他结构保存所有数据(S4?)

到目前为止的方法:

  1. 通过计算列数来获取标题数据的行号
  2. 通过阅读上述向量中的每个行索引来获取标题
  3. 通过计算由标题行描述的索引中的数据集之间的跳过和缩进来读取数据。
  4. 从读取标题
  5. 中提取读取数据列名称

    在阅读标题和数据集时,我需要帮助让我走上正确的轨道以避免循环/使代码更具可读性/紧凑性。

    这些CSV格式化为普通CSV,只是它们包含或多或少任意数量的子表。对于我导出的每个数据集,结构是不同的。在当前示例中,我将假设CSV中包含五个表。

    为了给你一个想法,这里有一些带有行号的虚构样本数据。分隔符和引用已被删除:

    1:     n, Name, Species, Description, Classification
    2:     90, Mickey, Mouse, Big ears, rat
    3:     45, Minnie, Mouse, Big bow, rat
    ...
    16835: Code, Species
    16836: RT, rat
    ...
    22673: n, Code, Country
    22674: 1, RT, Murica
    ...
    33211: Activity, Code, Descriptor
    32212: running, RU, senseless activity
    ...
    34749: Last update
    34750: 2017/05/09 02:09:14
    

    有很多方法可以读取每个数据集。到目前为止我想出了什么:

    filepath <- file.path(paste0(Sys.getenv("USERPROFILE"), "\\SAMPLE.CSV)
    
    # Make a vector with column number per line
    fieldVector <- utils::count.fields(filepath, sep = ",", quote = "\"")
    
    # Make a vector with unique number of fields in file
    nFields <- base::unique(fieldVector)
    
    # Make a vector with indices for position of new dataset
    iHeaders <- base::match(nFields, fieldVector)
    

    有了这个,我可以做以下事情:

    header <- utils::read.csv2(filepath, header = FALSE, sep = ",", quote = "\"", skip = iHeaders[4], nrows = iHeaders[5]-iHeaders[4]-1)
    
    data <- utils::read.csv2(filepath, header = FALSE, sep = ",", quote = "\"", skip = iHeaders[4] + 1, nrows = iHeaders[5]-iHeaders[4]-1)
    
    names(data) <- header
    

    正如在这篇文章的介绍中,我已经做了一些函数,这使得更容易为每个数据集获取标题:

    Headers <- GetHeaders(filepath, iHeaders)
    colnames(data) <- Headers[[4]]
    

    我现在有两个函数 - 一个是GetHeader,它使用utils :: read.csv2从文件中捕获一行,同时确保安全的headernames(没有æøå%等)。

    另一个返回包含所有标题的字符串向量列表:

    GetHeaders <- function(filepath, linenums) {
        # init an empty list of length(linenums) 
        l.headers <-  vector(mode = "list", length = length(linenums))
    
        for(i in seq_along(linenums)) {
                # read.csv2(filepath, skip = linenums[i]-1, nrows = 1)
            l.headers[[i]] <- GetHeader(filepath, linenums[i])
        }
        l.headers
    }
    

    我所挣扎的是如何一次性阅读所有可能的数据集。具体来说,如果我应该编写一个通用函数,最后一组有点难以理解,我只知道标题的行号,而不是以下数据中的行数。

    此外,所描述的这种结构的最佳数据结构是什么?子表中的数据彼此相关(可用于标准化部分数据)。我知道我必须为每个读取的CSV做手工工作,但是因为我必须阅读这些文件的TONS,所以在每次通过时以可预测的方式构造它们的一些常用功能将是非常好的。

    在回答之前,请记住,不,使用不同的导出格式不是一种选择。

    非常感谢您的任何指示。我是R的初学者,并没有完全围绕这个特定领域的所有可能的解决方案。

0 个答案:

没有答案