использование имен столбцов при добавлении данных в write.table

#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)