#r
#r
Вопрос:
Я перебираю некоторые данные и добавляю их в файл csv. Я хочу, чтобы имена столбцов были в верхней части файла один раз, а затем, когда он зацикливается, не повторять имена столбцов в середине файла.
Если я это сделаю col.names=T
, он повторяется, включая имена столбцов для каждого нового цикла. Если у меня есть col.names=F
, имен столбцов вообще нет.
Как мне сделать это наиболее эффективно? Я чувствую, что это такой распространенный случай, что должен быть способ сделать это, не написав специально код для его обработки.
write.table(dd, "data.csv", append=TRUE, col.names=T)
Комментарии:
1. непроверенный, но вы могли бы сделать
col.names = ifelse(ii %in% 1, TRUE, FALSE)
, где ii — ваша итерация цикла2. Я действительно не думаю, что это так часто, как вы думаете. Обычно вы сначала создаете весь data.frame, а затем записываете его один раз.
3. При работе с большими наборами данных сначала может быть невозможно создать весь фрейм данных в памяти
Ответ №1:
См ?file.exists
. .
write.table(dd, "data.csv", append=TRUE, col.names=!file.exists("data.csv"))
Таким образом, имена столбцов записываются только тогда, когда вы не добавляете к файлу, который уже существует.
Комментарии:
1. Я поспорил с принятым ответом. Это сработало как заклинание. Спасибо.
Ответ №2:
Вы также можете столкнуться с проблемой, связанной с идентичностью имен строк, поскольку write.table
при добавлении не допускаются одинаковые имена строк. Вы могли бы попробовать это. При первой записи в файл попробуйте write.table
использовать row.names = FALSE
только. Затем, начиная со второй записи в файл, используйте оба col.names = FALSE
и row.names = FALSE
Вот первая запись в файл
> d1 <- data.frame(A = 1:5, B = 1:5) ## example data
> write.table(d1, "file.txt", row.names = FALSE)
Мы можем проверить это с read.table("file.txt", header = TRUE)
помощью . Затем мы можем добавить тот же фрейм данных в этот файл с
> write.table(d1, "file.txt", row.names = FALSE,
col.names = FALSE, append = TRUE)
И снова мы можем проверить это с помощью read.table("file.txt", header = TRUE)
Итак, если у вас есть список фреймов данных, скажем dlst
, ваш фрагмент кода, который добавляет фреймы данных вместе, может выглядеть примерно так
> dlst <- rep(list(d1), 3) ## list of example data
> write.table(dlst[1], "file.txt", row.names = FALSE)
> invisible(lapply(dlst[-1], write.table, "file.txt", row.names = FALSE,
col.names = FALSE, append = TRUE))
Но, как предлагает @MrFlick, было бы намного лучше добавить фреймы данных в R, а затем отправить их в файл один раз. Это устранило бы многие возможные ошибки / проблемы, которые могут возникнуть при записи в файл. Если данные находятся в списке, это можно было бы сделать с помощью
> dc <- do.call(rbind, dlst)
> write.table(dc, "file.txt")
Комментарии:
1. Спасибо за ваш комментарий. Когда я пытаюсь сделать то, что вы предложили, я получаю следующую ошибку: Ошибка в write.table(dd, «data.csv», raw.names = FALSE): неиспользуемый аргумент (raw.names = FALSE)
2. Изначально у меня не было проблем с именами строк.
3. @user1754606, вы получаете эту ошибку, потому что вы неправильно написали «строка» как «необработанная»
4. Спасибо! отлично, извините за «сырой»/
5. возможно , было бы лучше создать единственное соединение , к которому вы переходите
write.table
. Вы можете оставить соединение открытым до тех пор, пока не закончите с ним, вместо того чтобы открывать и закрывать его каждый раз, когда вы пишете. Смотрите примеры в?connections
Ответ №3:
Попробуйте изменить имена столбцов фрейма данных с помощью names()
command в R и заменить их теми же именами , что и существующие , а затем попробуйте dbWriteTable
сохранить команду row.names = False
. Проблема будет решена. например
, если ваш фрейм данных df1
содержит столбцы как obs
, name
, age
то
names(df1) <- c('obs','name','age')
а потом попробуй
dbWriteTable(conn, 'table_name', df1, append = T, row.names = F)