У меня есть различные файлы .txt, хранящиеся в нескольких папках. Файлы txt имеют различные столбцы, один из которых — «Температура». В некоторых файлах имя столбца температуры указано как T2 [°C], а в других — как T2 [?C]. Я хочу сохранить имя столбца температуры как T2 [°C] во всех файлах. Я не хочу менять имена других столбцов. Кроме того, количество столбцов во всех файлах неодинаково. (например, в нескольких файлах есть такие столбцы, как давление, температура, радиация, скорость ветра, направление ветра, а в других файлах есть только давление, температура и радиация. Это можно рассматривать как случай отсутствия данных. Отсутствующие столбцы можно добавить со значениями NA , Чтобы решить проблему с именем столбца температуры и количеством столбцов, я использую следующий код в R, но в итоге выдает ошибку: Ошибка в rbindlist (dt.tidied, fill = TRUE): столбец атрибута класса 1. элемента 142 не соответствует столбцу 1 элемента 23. 'Может ли кто-нибудь помочь мне, как изменить код для устранения ошибки.
install.packages("data.table")
library(data.table)
#List of files
filelist <- list.files("C:/Users/Akanksha/Desktop/BSRN/Test_Gz", full.names = TRUE, recursive
= TRUE, pattern = ".txt$")
#Read the files
dt <- lapply(filelist, fread, skip = 27)
#Adjust Column names
dt.tidied <- lapply(dt, FUN = function(x){
#adjust ? to degree
setnames(x, old = "T2 [?C]", new = "T2 [°C]", skip_absent = TRUE)
colnames(x) <- gsub("\\[", "(", colnames(x))
colnames(x) <- gsub("\\]", ")", colnames(x))
#return
return(x)
})
#bind, filling missing columns to NA
merged <- rbindlist(dt.tidied, fill = TRUE, use.names = TRUE)
Я попытался проверить атрибут класса и нашел следующий ответ. Оба возвращают одинаковые ответы, тогда я не понимаю, что вызывает ошибку. Кто-нибудь может мне помочь, пожалуйста.
> class(dt.tidied[[23]][1])
[1] "data.table" "data.frame"
> class(dt.tidied[[142]][1])
[1] "data.table" "data.frame"
> d1=dput(dt.tidied[[23]])
structure(list(V1 = c(NA, NA, NA), V2 = c("SRad(SRAD)",
"Temp [?C] (TT)", "Temp QCode (TTC)"
)), row.names = c(NA, -3L), class = c("data.table", "data.frame"
), .internal.selfref = <pointer: (0x00000152b22fe7b0)>)
> d1=dput(dt.tidied[[142]])
956.902, 961.01, 965.114)), row.names = c(NA, -44615L), class =
c("data.table", "data.frame"), .internal.selfref = <pointer:
0x000001afc82f7590>) #The result of dput(dt.tidied[[142]] was too
large, I am unable to see the initial lines, hence, I am pasting the
last few lines of the result.
Кроме того, код выдает следующую ошибку после dt <- lapply(...)
Error in FUN(X[[i]], ...) : skip=27 but the input only has 25 lines
In addition: There were 50 or more warnings (use warnings() to see the
first 50)
Обновление редактирования: я проверил свои данные и обнаружил, что мне нужно пропустить разное количество строк в разных текстовых файлах. Может ли это быть причиной ошибки? И как это исправить? Один из способов, который я могу придумать, - это прочитать файлы из строки, следующей за */, потому что следующая строка до */ является заголовком, а затем начинаются данные. Он общий для всех файлов. Пожалуйста, помогите.
В обоих файлах первый столбец — «Дата/время» (заголовок столбца). В обоих файлах данные записываются как 2004-08-01T00:00:00 (хотя даты начала в обоих файлах разные, но у всех файлов разные даты начала). Не могли бы вы помочь мне изменить код для устранения ошибки.
Попробуйте следующее и отредактируйте свой вопрос с результатом. class(dt.tidied[[23]][1]) и class(dt.tidied[[142]][1])
@On_an_island Добавил результаты, но они одинаковы для обоих предметов. Я не понимаю, что вызывает ошибку тогда. Не могли бы вы помочь.
@On_an_island Я обновил свой вопрос, добавив некоторые подробности о вводе. Не могли бы вы помочь.
Не имея доступа к данным, с которыми вы работаете, мне будет сложно сказать вам, как именно это исправить. Похоже, что, как вы указали, проблема может заключаться в том, что вы импортируете файлы, а данные содержат строки заголовков. Доступны ли данные, с которыми вы работаете, общедоступны? Если это так, я могу лучше понять, что происходит на самом деле, и попытаться найти решение.
Нет, в открытом доступе нет.
можете ли вы сделать: d1=dput(dt.tidied[[23]]) и d2=dput(dt.tidied[[142]]) и скопировать и вставить результаты в свой ответ.





dput, который вы предоставили dt.tidied[[142]], был неполным, поэтому я объясню, что может произойти, на примере. Предположим, что ваши таблицы данных d1 и d2 выглядят так:
library(lubridate)
d1 = structure(
list(V1 = c(NA, NA, NA),
V2 = c("SRad(SRAD)","Temp [?C] (TT)", "Temp QCode (TTC)")),
row.names = c(NA, -3L),
class = c("data.table", "data.frame")
)
d2 = structure(
list(V1 = c(NA, NA, NA),
V2 = c(956.902, 961.01, 965.114)),
row.names = c(NA, -44615L),
class = c("data.table", "data.frame")
)
Мы создадим список для хранения этих двух data.tables и сохраним их в элементах 1 и 2 списка:
dt.tidied.working <- vector("list", length = 2)
dt.tidied.working[[1]] <- d1
dt.tidied.working[[2]] <- d2
Теперь мы можем проверить атрибут класса столбца 1 для каждого элемента списка:
> class(dt.tidied.working[[1]]$V1)
[1] "logical"
> class(dt.tidied.working[[2]]$V1)
[1] "logical"
Итак, мы видим, что в этом очень простом примере оба столбца имеют один и тот же класс, logical, поэтому, когда мы используем rbindlist, мы не получим ошибку, которую вы получаете.
merged <- rbindlist(dt.tidied.working, fill = TRUE, use.names = TRUE)
V1 V2
1: NA SRad(SRAD)
2: NA Temp [?C] (TT)
3: NA Temp QCode (TTC)
4: NA 956.902
5: NA 961.01
6: NA 965.114
Теперь давайте изменим атрибут класса для второй таблицы данных на то, что, как я думаю, может содержать ваша полная таблица данных, основываясь на ваших комментариях:
## not working example
d1 = structure(
list(V1 = c(NA, NA, NA),
V2 = c("SRad(SRAD)","Temp [?C] (TT)", "Temp QCode (TTC)")),
row.names = c(NA, -3L),
class = c("data.table", "data.frame")
)
d2 = structure(
list(V1 = ymd_hms(c("2004-08-01T00:00:00","2004-08-02T00:00:00","2004-08-03T00:00:00")),
V2 = c(956.902, 961.01, 965.114)),
row.names = c(NA, -44615L),
class = c("data.table", "data.frame")
)
dt.tidied.not.working <- vector("list", length = 2)
dt.tidied.not.working[[1]] <- d1
dt.tidied.not.working[[2]] <- d2
Теперь мы снова проверим атрибуты класса, как в предыдущем примере, и вы увидите, что два столбца теперь имеют разные атрибуты, и когда мы попытаемся rbind.list, вы получите ту же ошибку.
> class(dt.tidied.not.working[[1]]$V1)
[1] "logical"
> class(dt.tidied.not.working[[2]]$V1)
[1] "POSIXct" "POSIXt"
> merged <- rbindlist(dt.tidied.not.working, fill = TRUE, use.names = TRUE)
Error in rbindlist(dt.tidied.not.working, fill = TRUE, use.names = TRUE) :
Class attribute on column 1 of item 2 does not match with column 1 of item 1.
Возможное решение
Основываясь на вашем выводе dt.tidied[[23]], кажется, что у вас есть значения NA там, где должны быть значения ymd_hms. Это может быть проблемой, с которой вы столкнулись. Если это так, то вы можете проверить элементы списка dt, который содержит файлы, которые вы читаете, чтобы увидеть, какие файлы имеют NA в столбце V1. Если это действительно проблема, вам нужно будет выяснить, что делать с этими наблюдениями (удалить их или исправить, назначив значения даты/времени).
Кроме того, вывод d1=dput(dt.tidied[[142]]), который вы предоставили в своем вопросе, является неполным, поскольку вы не включили structure(... так же, как для d1=dput(dt.tidied[[23]]). Пожалуйста, предоставьте полную и точную информацию, чтобы нам было легче вам помочь.
Если вы не хотите проверять каждый элемент вашего списка dt, вы можете использовать функцию rbind.fill из библиотеки plyr:
library(plyr)
dt.tidied.not.working <- lapply(dt.tidied.not.working, function(x) as.data.frame(x))
merged <- plyr::rbind.fill(dt.tidied.not.working)
> merged
V1 V2
1 NA SRad(SRAD)
2 NA Temp [?C] (TT)
3 NA Temp QCode (TTC)
4 1.091e+09 956.902
5 1.091e+09 961.01
6 1.091e+09 965.114
какие данные представляет столбец 1? R сообщает вам, что когда он сравнивает классы первого столбца для всех таблиц данных в вашем списке, элементы списка 23 и 142 имеют разные классы для столбца 1 (т. е. элемент 23 может иметь столбец 1 как дату, а элемент 142 может иметь столбец 1). как персонаж).