В R как читать строку CSV-файл построчно и распознавать ли содержимое как правильный тип данных?

r csv

14897 просмотра

7 ответа

Я хочу прочитать в файле CSV, чья первая строка - это имена переменных, а последующие строки - содержимое этих переменных. Некоторые из переменных являются числовыми, а некоторые - текстовыми, а некоторые даже пустыми.

file = "path/file.csv"
f = file(file,'r')
varnames = strsplit(readLines(f,1),",")[[1]]
data = strsplit(readLines(f,1),",")[[1]]

Теперь, когда данные содержат все переменные, как мне сделать так, чтобы данные могли распознавать читаемый тип данных, как если бы я это сделал read.csv.

Мне нужно читать данные построчно (или n строк за раз), так как весь набор данных слишком велик для чтения в R.

Автор: xiaodai Источник Размещён: 10.09.2019 02:42

Ответы (7)


11 плюса

Основываясь на комментарии DWin, вы можете попробовать что-то вроде этого:

read.clump <- function(file, lines, clump){
    if(clump > 1){
        header <- read.csv(file, nrows=1, header=FALSE)
        p = read.csv(file, skip = lines*(clump-1), 
       #p = read.csv(file, skip = (lines*(clump-1))+1 if not a textConnection           
            nrows = lines, header=FALSE)

        names(p) = header
    } else {
        p = read.csv(file, skip = lines*(clump-1), nrows = lines)
    }
    return(p)
}

Вы, вероятно, должны также добавить некоторую обработку ошибок / проверку в функцию.

Затем с

x = "letter1, letter2
a, b
c, d
e, f
g, h
i, j
k, l"


>read.clump(textConnection(x), lines = 2, clump = 1)
  letter1 letter2
1       a       b
2       c       d

> read.clump(textConnection(x), lines = 2, clump = 2)
  letter1  letter2
1       e        f
2       g        h

> read.clump(textConnection(x), lines = 3, clump = 1)
  letter1 letter2
1       a       b
2       c       d
3       e       f


> read.clump(textConnection(x), lines = 3, clump = 2)
  letter1  letter2
1       g        h
2       i        j
3       k        l

Теперь вам просто нужно * применить над комками

Автор: Greg Размещён: 25.05.2011 05:11

6 плюса

Альтернативная стратегия, которая обсуждалась здесь ранее для работы с очень большими (скажем,> 1e7ish ячейками) файлами CSV:

  1. Считайте файл CSV в базу данных SQLite.
  2. Импортируйте данные из базы данных read.csv.sqlиз sqldfпакета.

Основными преимуществами этого являются то, что это обычно быстрее, и вы можете легко фильтровать содержимое, чтобы включить только те столбцы или строки, которые вам нужны.

Посмотрите, как импортировать CSV в sqlite с помощью RSqlite? для получения дополнительной информации.

Автор: Richie Cotton Размещён: 25.05.2011 09:34

4 плюса

Просто для удовольствия (я жду здесь долго выполняющихся вычислений :-)), версии, которая позволяет вам использовать любые read.*из функций, и которая содержит решение крошечной ошибки в коде \ Greg:

read.clump <- function(file, lines, clump, readFunc=read.csv,
    skip=(lines*(clump-1))+ifelse((header) & (clump>1) & (!inherits(file, "connection")),1,0),
    nrows=lines,header=TRUE,...){
    if(clump > 1){
            colnms<-NULL
            if(header)
            {
                colnms<-unlist(readFunc(file, nrows=1, header=FALSE))
                print(colnms)
            }
      p = readFunc(file, skip = skip,
          nrows = nrows, header=FALSE,...)
            if(! is.null(colnms))
            {
        colnames(p) = colnms
            }
    } else {
        p = readFunc(file, skip = skip, nrows = nrows, header=header)
    }
    return(p)
}

Теперь вы можете передать соответствующую функцию как параметр readFunc, а также передать дополнительные параметры. Мета-программирование - это весело.

Автор: Nick Sabbe Размещён: 25.05.2011 09:35

3 плюса

Об одном замечании: если у вас действительно есть эти огромные данные, есть (рядом с решением SQLite) различные пакеты, которые помогут вам справиться с этим, не прибегая к хитростям, как описано в этих ответах.

Там есть ffи bigmemoryпакет с друзьями biganalytics, bigtabulate'biglm' и так далее. Для обзора см. Например.

Автор: Joris Meys Размещён: 25.05.2011 11:41

1 плюс

Я бы попробовал пакет LaF :

Методы быстрого доступа к большим файлам ASCII ... Предполагается, что файлы слишком велики, чтобы уместиться в память ... Предоставляются методы для доступа и обработки файлов по блокам. Кроме того, к открытому файлу можно получить доступ как к обычному data.frame ...

Я смог заставить его работать с приведенным ниже примером кода, и он, похоже, имел производительность, ожидаемую от потоковой реализации. Тем не менее, я бы порекомендовал вам проводить собственные тесты времени.

library('LaF')

model <- detect_dm_csv('data.csv', header = TRUE, nrows = 600)  # read only 600 rows for type detection

mylaf <- laf_open(model)

print(mylaf[1000])  # print 1000th row
Автор: daveagp Размещён: 22.11.2017 12:21

0 плюса

Решение

Вы можете использовать chunked или, disk.frameесли не возражаете, немного поработать над записью своих данных.

У обоих есть варианты, позволяющие вам читать данные по частям

Автор: xiaodai Размещён: 01.11.2018 10:26

0 плюса

Я думаю, что использование disk.frame's csv_to_disk.frameи установка in_chunk_sizeбыло бы здорово для этого варианта использования. Например

library(disk.frame)
csv_to_disk.frame("/path/to/file.csv", in_chunk_size = 1e7)
Автор: xiaodai Размещён: 09.09.2019 11:41
Вопросы из категории :
32x32