Добавить имя файла в виде столбца к data.frame внутри цикла

#r #for-loop

#r #для цикла

Вопрос:

У меня есть PDF-файлы, которые я считываю в R. Я преобразую их в data.frame с помощью tabluizer::extract_tables

Файлы PDF содержат 6 столбцов / переменных и могут содержать несколько страниц в документе … отлично, это работает. Что я хочу сделать, так это добавить 7-й столбец для имени файла внутри моего цикла for, но не удается, поскольку я получаю ошибку:

 Error in rbind(deparse.level, ...) : numbers of columns of arguments do not match
  

Вот мой код:

   for(i in 1:length(pdf.list)){
  print(paste("Reading - ", pdf.list[i]))
  cur.doc <- extract_tables(pdf.list[i])
  for(j in 1:length(cur.doc)){
    cur.doc.page <- cur.doc[[j]]
    df$FileName = pdf.list[i]
    df <- as.data.frame(cur.doc.page)
    documents <- rbind(documents, df)
    }
  }
  

Итак, я понимаю, что проблема в моей cbind (), но я не уверен в а) почему и б) как исправить. pdf.list[i] задает текущее имя файла.

Обновить

Это, наконец, сделано, все приведет к ошибкам

 documents <- data.frame()
error.page.df <- data.frame()

for(i in 1:length(pdf.list)){
  print(paste("Reading file -", pdf.list[i]))
  cur.doc <- extract_tables(pdf.list[i])
  print(paste("There are", length(cur.doc), "pages in the current file."))
  for(j in 1:length(cur.doc)){
    cur.doc.page <- cur.doc[j]
    print(
      paste(
        "Reading page -"
        , j
        , "There are"
        , ncol(as.data.frame(cur.doc.page))
        , "columns."
        )
      )
    df <- as.data.frame(cur.doc.page)
    df <- df[-1, ]
    df <- df[, colSums(df != "") != 0]
    df$FileName <- pdf.list[i]
    tmp.col.names <- c(
      "V1","V2","V3","V4","V6","FileName"
    )
    try(colnames(df) <- tmp.col.names, silent = T)
    possible.error <- try(rbind(documents, df))
    if(isTRUE(class(possible.error)=="try-error")) { 
      print(
        paste(
          "Could not insert page"
          , j
          , "for file -"
          , pdf.list[i]
        )
      )
      error.msg <- paste(
        "Could not insert page"
        , j
        , "for file -"
        , pdf.list[i]
      )
      error.page.df <- rbind(error.page.df, error.msg)
      next 
    } else {
      documents <-rbind(documents, df)
      possible.error <- NA
    }
  }
}
  

Комментарии:

1. ваша индексация может быть проблемой, вы используете i дважды

2. внесенная модификация все еще не работает, хотя

Ответ №1:

Сложно сказать… Я думаю, у вас может быть больше ошибок. Возможно for (j in 1:length(cur.doc)) , нет 1:length(cur.doc[i]) . И вы создаете, df но никогда не используете его … вы имеете в виду documents <- rbind(documents, df) , а не rbind(documents, cur.doc.page) ?

В любом случае, я думаю, вы хотите добавить новый столбец только в текущий документ, а не во весь documents фрейм данных. То, как это кодируется сейчас, вы добавляете совершенно новый столбец documents каждый раз через внутренний цикл. Но rbind требуется, чтобы у вас было одинаковое количество столбцов.

Я предполагаю, что вы хотите использовать df , поэтому добавьте столбец в df перед привязкой к docs:

 df$filename = pdf.list[i]
  

(Вы используете pdf.list[j] в своем коде, но кажется, что это должно быть [i] как в вашем тексте).

Вот так:

 documents <- data.frame()
for(i in 1:length(pdf.list)){
  print(paste("Reading - ", pdf.list[i]))
  cur.doc <- extract_tables(pdf.list[i])
  for(j in 1:length(cur.doc)){
    cur.doc.page <- cur.doc[[j]]
    df <- as.data.frame(cur.doc.page)
    df$FileName <- pdf.list[i]
    documents <- rbind(documents, df)
  }
}
  

Комментарии:

1. Я отредактировал свой код выше, но все равно получаю ту же ошибку, да, вы правы, я хотел использовать df

2.Ставьте df$FileName = pdf.list[i] после df <- as.data.frame(cur.doc.page) , иначе вы просто перезапишете df . Также убедитесь, что вы начали с чистого листа documents = data.frame() или что-то подобное перед циклом.

3. номера аргументов столбцов все еще не совпадают, странно.

4. Хорошо. Итак, согласно вашему print заявлению, в каком документе оно находится? Насколько вы уверены, что количество столбцов в каждом PDF-файле соответствует? Проверьте этот документ. Возможно, добавьте print(df) или print(head(df)) прямо перед вашей rbind() строкой, чтобы вы могли видеть, что происходит.

5. documents <- data.frame() for(i in 1:length(pdf.list)){ print(paste("Reading - ", pdf.list[i])) cur.doc <- extract_tables(pdf.list[i]) for(j in 1:length(cur.doc[i])){ cur.doc.page <- cur.doc[[j]] df <- as.data.frame(cur.doc.page) df$FileName <- pdf.list[i] documents <- rbind(documents, df) } } получилось