#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(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) } }
получилось