【问题标题】:Reading broken CSV lines from R从 R 读取损坏的 CSV 行
【发布时间】:2019-09-26 23:15:57
【问题描述】:

我需要读取一个 csv 文件,该文件由于某些原因而出现断行。大约有 60,000 行,其中一些刚刚从以前的原始数据中删除。 我想知道如何读取表格并将其转换为适当的数据框

I am reading the file this way: 
All_transactions <- read.csv(paste("/Users/Match/Data/MenuReport/", 04-01-new_file.csv, sep=""), skip=6, sep=",")

我正在跳过包含随机文本的前 6 行。

Product,Date,Quantity,Categorie,sector
ABC, 01052019, 4510, Food, Dry
CDE, 01052019, 222, Drink
, Cold
FGH, 01052019, 345, Food, Dry
IJK, 01052019, 234, Food
, Cold

我确实注意到错误的行似乎以逗号开头

我希望能够以这种方式清洁它们:

Product,Date,Quantity,Categorie,sector
ABC, 01052019, 4510, Food, Dry
CDE, 01052019, 222, Drink, Cold
FGH, 01052019, 345, Food, Dry
IJK, 01052019, 234, Food, Cold

然后将它们放入数据框中。

【问题讨论】:

    标签: r csv dataframe


    【解决方案1】:

    可能有几种方法可以做到这一点..

    更新:然后试试这个。使用scan()中的skip=参数,您可以指定要跳过的行数。

    
    
    file <- scan("C:/Users/skupfer/Documents/bisher.txt", strip.white = TRUE, sep = ",",
                 what = list("character"), skip = 1)
    
    file_mat <- matrix(file[[1]][file[[1]] != ""], ncol = 5, byrow = TRUE)
    
    file_df <- as.data.frame(file_mat, stringsAsFactors = FALSE)
    
    file_df$Quantity <- as.integer(file_mat[,3])
    
    > file_df
      Product     Date Quantity Categorie sector
    1     ABC 01052019     4510      Food    Dry
    2     CDE 01052019      222     Drink   Cold
    3     FGH 01052019      345      Food    Dry
    4     IJK 01052019      234      Food   Cold
    
    
    

    【讨论】:

    • 请问如何跳过前 6 行?
    • 嘿,这个想法闪过我的脑海,这就是我最终按照上述评论所做的事情。现在,文件要每天生成,我不确定让同事每天打开文件删除行有多好,当我们可以用一行代码修复它并安全起见时。
    【解决方案2】:

    最简单的方法是使用 readrs read_file 将 CSV 的内容作为单个字符串读取,然后用逗号替换模式换行符 + 逗号:

    library(readr)
    
    # Read in broken CSV as single character string.
    file_string <- read_file("broken_csv.csv")
    
    # Replace patter `\\n,` with `,`, then read string as CSV.
    df <- read_csv(gsub("\\n,", ",", file_string), skip = 6)
    
    df
    
    #### OUTPUT ####
    
    # A tibble: 4 x 5
      Product Date     Quantity Categorie sector
      <chr>   <chr>       <dbl> <chr>     <chr> 
    1 ABC     01052019     4510 Food      Dry   
    2 CDE     01052019      222 Drink     Cold  
    3 FGH     01052019      345 Food      Dry   
    4 IJK     01052019      234 Food      Cold  
    

    【讨论】:

    • 我正在尝试这种方法,到目前为止它已经运行了10分钟,....我想我别无选择。该文件有 60k 行长,但可能会增长 10-f。快速提问,使用 read_csv,如何删除前 6 行?
    • 我手动删除了前 6 行,但我遇到了触发 R 重启的致命错误。
    • 使用read_csv 中的skip 参数来跳过行。在read_file 中没有skip,但在read_lines 中有,所以你也可以使用它,然后用\n 折叠向量。请记住,列名也会被跳过。我刚刚根据您提供的示例数据从模拟数据中创建了 120,000 行并运行了代码。不到一秒钟就完成了。数据肯定有其他问题。能否给我们一个更具代表性的样本?
    【解决方案3】:

    其他解决方案可能更好,但您也可以使用这样的巨大功能代码(这在很大程度上依赖于遵循示例数据模式的其余数据):

    library(readr)
    
    df <- read_csv(file = "YOUR_FILE", skip = 6)
    df
    
    process_df <- function(x) {
      for (row in 1:nrow(x)) {
        if(sum(is.na(x[row,]) == 1)) {
          if (rowSums(!is.na(x[row+1,])) == 1) {
            x[row, which(is.na(x[row,]))] <- x[row+1,which(!is.na(x[3,]))]
          }
        }
      }
      x <- x[rowSums(!is.na(x[,])) > 1,]
      return(x)
    }
    
    process_df(df)
    

    【讨论】:

    • 如何跳过前 6 行?它似乎不起作用。
    • 我更改了我的答案,以展示如何删除前 6 行。
    • 一个问题,随机文本(应该被跳过)是在标题之前还是在标题之后? (在Product,Date,Quantity,Categorie,sector 之前或之后)。如果数据在标题之前,那么skip = 6 将起作用。否则,您应该在下面执行@bJust 之类的操作。
    【解决方案4】:

    使用基础 R 的简单解决方案: 使用 readLines 读取,跳过前 6 个,然后进一步处理:

    dat = readLines('your_file')
    dat = dat[7:length(dat)]
    csv_dat = read.csv(textConnection(dat[!grepl("^,",dat)]))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-26
      • 1970-01-01
      • 2016-07-18
      • 1970-01-01
      • 2010-09-16
      • 2020-11-07
      • 2013-10-29
      • 1970-01-01
      相关资源
      最近更新 更多