Чтение файла в R

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

В файле data.txt есть данные, записанные как:

04001400 HI 34.50 118.27 19480701 08 LST
         0   0   0   0   0   0   0   0   0   0   0   0
       MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS
04001400 HI 34.50 118.27 19480801 08 LST
         0   0   0   0   0   0   0   0   0   0   0   0
       MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS
04001400 HI 34.50 118.27 19480901 08 LST
         0   0   0   0   0   0   0   0   0   0   0   0
       MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS

первое число - номер станции, HI - случай, третье и четвертое числа - координаты широты и долготы, другое число - год, месяц, день, а другое число (08) - часовой пояс, за которым следует LST, означающая период времени. Следующие 24 числа или в приведенном выше примере нули и MIS являются значениями для определенного региона и времени. Я пытаюсь сохранить содержимое файла в виде таблицы в этом формате формата [n x 31] (где 31 - количество столбцов, а n - общее количество строк в файле):

04001400 HI 34.50 118.27 19480701 08 LST 0   0   0   0   0   0   0   0   0   0   0   0 MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS

04001400 HI 34.50 118.27 19480801 08 LST 0   0   0   0   0   0   0   0   0   0   0   0 MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS

04001400 HI 34.50 118.27 19480901 08 LST 0   0   0   0   0   0   0   0   0   0   0   0 MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS

Я пробовал кодировать его таким образом на основе функции read.table:

data <- read.table("data.txt", sep = c("\b", "\t", "\n"))

Но это не работает, как я описал выше. Как я могу это сделать? Спасибо за помощь.


person Luciano Rodriguez    schedule 19.03.2012    source источник


Ответы (2)


Вы можете использовать scan для чтения многострочных данных, тем более что это особый формат.

dat <- data.frame(scan("data.txt",
what = as.list(c("character","character","number","number",
                 "character","number","character",
                  rep("character",24))),
multi.line=TRUE))
names(dat) <- paste("V",1:ncol(dat),sep="")

который дает

> dat
        V1 V2    V3     V4       V5 V6  V7 V8 V9 V10 V11 V12 V13 V14 V15 V16
1 04001400 HI 34.50 118.27 19480701 08 LST  0  0   0   0   0   0   0   0   0
2 04001400 HI 34.50 118.27 19480801 08 LST  0  0   0   0   0   0   0   0   0
3 04001400 HI 34.50 118.27 19480901 08 LST  0  0   0   0   0   0   0   0   0
  V17 V18 V19 V20 V21 V22 V23 V24 V25 V26 V27 V28 V29 V30 V31
1   0   0   0 MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS
2   0   0   0 MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS
3   0   0   0 MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS MIS
> dim(dat)
[1]  3 31

Вы, конечно, можете дать столбцам более информативные имена.

РЕДАКТИРОВАТЬ:

Как указывает Джош в комментариях, мой аргумент what имел неправильный формат и привел к тому, что все столбцы были импортированы как символы, а не некоторые как символы, а некоторые как числовые. Он должен был читать:

dat <- data.frame(scan("data.txt",
what = list(character(), character(), numeric(), numeric(),
            character(), numeric(), character(),
            character(), character(), character(), character(),
            character(), character(), character(), character(),
            character(), character(), character(), character(),
            character(), character(), character(), character(),
            character(), character(), character(), character(),
            character(), character(), character(), character()),
multi.line=TRUE))
names(dat) <- paste("V",1:ncol(dat),sep="")

что дает более подходящие:

> str(dat)

'data.frame':   3 obs. of  31 variables:
 $ V1 : Factor w/ 1 level "04001400": 1 1 1
 $ V2 : Factor w/ 1 level "HI": 1 1 1
 $ V3 : num  34.5 34.5 34.5
 $ V4 : num  118 118 118
 $ V5 : Factor w/ 3 levels "19480701","19480801",..: 1 2 3
 $ V6 : num  8 8 8
 $ V7 : Factor w/ 1 level "LST": 1 1 1
 $ V8 : Factor w/ 1 level "0": 1 1 1
 $ V9 : Factor w/ 1 level "0": 1 1 1
 $ V10: Factor w/ 1 level "0": 1 1 1
 $ V11: Factor w/ 1 level "0": 1 1 1
 $ V12: Factor w/ 1 level "0": 1 1 1
 $ V13: Factor w/ 1 level "0": 1 1 1
 $ V14: Factor w/ 1 level "0": 1 1 1
 $ V15: Factor w/ 1 level "0": 1 1 1
 $ V16: Factor w/ 1 level "0": 1 1 1
 $ V17: Factor w/ 1 level "0": 1 1 1
 $ V18: Factor w/ 1 level "0": 1 1 1
 $ V19: Factor w/ 1 level "0": 1 1 1
 $ V20: Factor w/ 1 level "MIS": 1 1 1
 $ V21: Factor w/ 1 level "MIS": 1 1 1
 $ V22: Factor w/ 1 level "MIS": 1 1 1
 $ V23: Factor w/ 1 level "MIS": 1 1 1
 $ V24: Factor w/ 1 level "MIS": 1 1 1
 $ V25: Factor w/ 1 level "MIS": 1 1 1
 $ V26: Factor w/ 1 level "MIS": 1 1 1
 $ V27: Factor w/ 1 level "MIS": 1 1 1
 $ V28: Factor w/ 1 level "MIS": 1 1 1
 $ V29: Factor w/ 1 level "MIS": 1 1 1
 $ V30: Factor w/ 1 level "MIS": 1 1 1
 $ V31: Factor w/ 1 level "MIS": 1 1 1
person Brian Diggs    schedule 19.03.2012
comment
Спасибо за помощь, отлично работает! И, конечно же, я позаботился о названиях столбцов, просто чтение было самой сложной частью. - person Luciano Rodriguez; 20.03.2012
comment
Привет, Брайан. Аргумент what, который вы предоставили, читается во всех столбцах как символьные векторы - вероятно, не то, что вы планировали. Чтобы понять, почему, сравните результаты этих трех битов кода: scan(textConnection("A 1 B 2"), what=list("character", "number")); scan(textConnection("A 1 B 2"), what=list(character(), numeric())); и scan(textConnection("A 1 B 2"), what=list("UggaBugga", 111)). - person Josh O'Brien; 20.03.2012
comment
@ JoshO'Brien: То, что вы предложили, может быть причиной того, почему я не могу получить список уникальных идентификаторов для V1, как указано Brain, с помощью простого вызова unique (dat [1,])? Кроме того, как бы вы предложили изменить код Брайана, чтобы он включал числовые значения, а не все символы? - person Luciano Rodriguez; 20.03.2012
comment
@LucianoRodriguez Это отдельная проблема. Вместо этого вам следует попробовать unique(dat[ , 1] (что, как я теперь вижу, вы сделали). Чтобы читать в некоторых столбцах как числовые, просто замените любые экземпляры "number" в коде Брайана на numeric() (без кавычек). - person Josh O'Brien; 20.03.2012
comment
@ JoshO'Brien К сожалению, замена numeric () на все числа не создает тот же формат, что и раньше. Плюс ко всему мне было выдано предупреждение Предупреждение: In scan (file, what, nmax, sep, dec, quote, skip, nlines, na.strings,: количество прочитанных элементов не кратно количеству столбцов. Есть предложения? - person Luciano Rodriguez; 20.03.2012
comment
Две мысли. Если решение Брайана в противном случае работало, можно прочитать все столбцы в виде символьных столбцов и преобразовать определенные столбцы, например, dat$V3 <- as.numeric(dat$V3). Если его код выдавал вам ту же ошибку, это может указывать на то, что в некоторых из ваших строк данных отсутствовал один или несколько элементов данных. Я бы посоветовал опробовать код только на первых нескольких записях вашего файла данных, и, если они сработают, отталкиваться оттуда. (Если вы попробуете это сделать, вы можете взглянуть на аргумент nmax для сканирования, который контролирует количество записей, которые нужно прочитать). - person Josh O'Brien; 20.03.2012
comment
Я обнаружил дилемму со своим кодом. Как оказалось, к сожалению, у данных, приобретенных у USGS, есть дополнительный час (25 баллов вместо 24 баллов) или иногда на один час меньше, так как они связаны с другим часом. Поэтому я должен тщательно запустить код, чтобы посмотреть, где в файле есть несоответствие. Тем не менее, я благодарю вас за вашу помощь и терпение. - person Luciano Rodriguez; 20.03.2012
comment
Я предполагаю, что лишний или недостающий час связан с переходом на летнее время, где один день в году имеет 25 часов, а один день - 23. - person Brian Diggs; 20.03.2012
comment
Я консультировался с моим профессором, который работал с этим типом данных много лет назад, и дополнительный пункт - это общее количество осадков за день, которое следует удалить. Поэтому во время сканирования я должен определить, есть ли лишняя точка, чтобы я мог игнорировать ее, пропустив ее и перейдя к следующему значению. Я думаю, что единственный способ преодолеть это - чтение по символам, а не использование функции сканирования. - person Luciano Rodriguez; 21.03.2012

Другой способ

a <- read.table("sample.txt", fill=T);
aseq <- seq(1, dim(a)[1], by=3)
x <- data.frame(a[aseq, 1:7], a[aseq+1,], a[aseq+2,]) 

1: 7 необходимо, потому что read.table () создает столбцы NA.

person Apprentice Queue    schedule 19.03.2012