Как вы можете прочитать файл CSV в R с разным количеством столбцов

У меня есть редкий набор данных, тот, чье количество столбцов варьируется по длине, в формате CSV. Вот образец текста файла.

12223, University
12227, bridge, Sky
12828, Sunset
13801, Ground
14853, Tranceamerica
14854, San Francisco
15595, shibuya, Shrine
16126, fog, San Francisco
16520, California, ocean, summer, golden gate, beach, San Francisco

Когда я использую

read.csv("data.txt", header = F)

R будет интерпретировать набор данных как имеющий 3 столбца, потому что размер определяется из первых 5 строк. Есть ли способ заставить r поместить данные в большее количество столбцов?

3 ответа

Решение

Глубоко в ?read.table В документации есть следующее:

Количество столбцов данных определяется по первым пяти строкам ввода (или по всему файлу, если в нем меньше пяти строк) или по длине col.names если это указано и дольше. Это может быть неправильно, если fill или же blank.lines.skip are trueтак что уточняйте col.names при необходимости (как в "Примерах").

Поэтому давайте определимся col.names быть длиной X (где X - максимальное количество полей в вашем наборе данных) и установить fill = TRUE:

dat <- textConnection("12223, University
12227, bridge, Sky
12828, Sunset
13801, Ground
14853, Tranceamerica
14854, San Francisco
15595, shibuya, Shrine
16126, fog, San Francisco
16520, California, ocean, summer, golden gate, beach, San Francisco")

read.table(dat, header = FALSE, sep = ",", 
  col.names = paste0("V",seq_len(7)), fill = TRUE)

     V1             V2             V3      V4           V5     V6             V7
1 12223     University                                                          
2 12227         bridge            Sky                                           
3 12828         Sunset                                                          
4 13801         Ground                                                          
5 14853  Tranceamerica                                                          
6 14854  San Francisco                                                          
7 15595        shibuya         Shrine                                           
8 16126            fog  San Francisco                                           
9 16520     California          ocean  summer  golden gate  beach  San Francisco

Если максимальное количество полей неизвестно, вы можете использовать полезную функцию полезности count.fields (который я нашел в read.table пример кода):

count.fields(dat, sep = ',')
# [1] 2 3 2 2 2 2 3 3 7
max(count.fields(dat, sep = ','))
# [1] 7

Возможно полезное связанное чтение: только чтение ограниченного числа столбцов в R

Вы можете прочитать данные так:

dat <- textConnection("12223, University
12227, bridge, Sky
12828, Sunset
13801, Ground
14853, Tranceamerica
14854, San Francisco
15595, shibuya, Shrine
16126, fog, San Francisco
16520, California, ocean, summer, golden gate, beach, San Francisco")

dat <- readLines(dat)
dat <- strsplit(dat, ",")

Это приводит к списку.

Это похоже на работу (следуя совету @BlueMagister):

tt <- read.table("~/Downloads/tmp.csv", fill=TRUE, header=FALSE, 
          sep=",", colClasses=c("numeric", rep("character", 6)))
names(tt) <- paste("V", 1:7, sep="")

     V1             V2             V3      V4           V5     V6             V7
1 12223     University                                                          
2 12227         bridge            Sky                                           
3 12828         Sunset                                                          
4 13801         Ground                                                          
5 14853  Tranceamerica                                                          
6 14854  San Francisco                                                          
7 15595        shibuya         Shrine                                           
8 16126            fog  San Francisco                                           
9 16520     California          ocean  summer  golden gate  beach  San Francisco

Я столкнулся с похожей проблемой, но count.fields из ответа Blue Magister не сработало, вероятно, потому, что запятые внутри полей противоречили sep=",". Кроме того, количество столбцов варьировалось от файла к файлу. Итак, я просто определил избытокcol.names в read.table(100 было достаточно в моем случае), а затем я использовал which(!is.na()) избавиться от лишних столбиков.

dat <- read.table("path/to/file.csv", col.names = paste("V",1:100), fill = T, sep = ",")
dat <- dat[,which(!is.na(dat[1,]))]

Попробуй, он более динамичный..

readVariableWidthFile <- function(filePath){
  con <-file(filePath)
  lines<- readLines(con)
  close(con)
  slines <- strsplit(lines,",")
  colCount <- max(unlist(lapply(slines, length)))

  FileContent <- read.csv(filePath,
                        header = FALSE,
                        col.names = paste0("V",seq_len(colCount)),
                        fill = TRUE)
  return(FileContent)
}
Другие вопросы по тегам