Выберите один столбец различной длины из множества файлов CSV и объедините в одну матрицу в R - PullRequest
1 голос
/ 10 ноября 2011

У меня есть 1000 CSV-файлов из dfr.jstor.org с двумя столбцами, KEYWORDS и WEIGHT.Длина каждого столбца варьируется от файла к файлу.Вот фрагмент одного файла CSV:

KEYTERMS  WEIGHT
canoe     1
archaic   0.273
pinus     0.191
florida   0.164

Я хочу использовать R, чтобы получить столбец KEYTERMS из каждого файла CSV и объединить его в один фрейм данных, например:

KEYTERMS_CSVFILENAME1 KEYTERMS_CSVFILENAME2 KEYTERMS_CSVFILENAME3
thwart                newsom                period 
dugout                site                  cypress 
sigma                 date                  hartmann 
precontact            NA                    florida 
orange                NA                    NA

Где CSVFILENAME1 - это имя файла CSV, из которого получены эти ключевые слова, а NA - пустая ячейка.

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

Ответы [ 3 ]

3 голосов
/ 10 ноября 2011

Чтобы сэкономить МАЛЕНЬКУЮ память / время, вы можете изменить решение @Ben Bolker следующим образом:

datlist <- lapply(csvnames,read.csv, colClasses=c("character", "NULL"))
rowseq <- seq_len( max(vapply(datlist,nrow, integer(1))) )
keylist <- lapply(datlist,function(x) { x[[1]][rowseq] ) })
names(keylist) <- paste(KEYTERMS,csvnames,sep="_")
#do.call(cbind,keylist)
do.call(data.frame,keylist)

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

Если вы сохранили старый способ заполнения, вы должны по крайней мере дополнить его NA_character_ вместо NA, чтобы избежать ненужного принуждения.

Я также индексирую столбец KEYTERMS по номеру вместо имени (так как должен быть только один). Я также изменил sapply на vapply, потому что он мне больше нравится :) - на самом деле он тоже быстрее.

Наконец вы сказали, что хотите data.frame. Последняя строка выдает это вместо матрицы.

3 голосов
/ 10 ноября 2011

Если вы вообще не ограничены объемом памяти, может работать что-то вроде:

datlist <- lapply(csvnames,read.csv)
maxlen <- max(sapply(datlist,nrow))
pad.NA <- function(x,len) {
   c(x,rep(NA_character_,len-length(x)))
}
keylist <- lapply(datlist,function(x) { pad.na(x[["KEYTERMS"]],maxlen) })
names(keylist) <- paste(KEYTERMS,csvnames,sep="_")
do.call(cbind,keylist)

( edit : добавлена ​​пропущенная скобка, NA_character_)

2 голосов
/ 10 ноября 2011

Вот несколько более простое решение с использованием ldply из plyr и reshape из base

# READ CSV FILES INTO LIST (i am using a dummy datlist for illustration)
# datlist <- lapply(csvnames,read.csv, colClasses=c("character", "NULL"))
datlist <- list(
  file1 = data.frame(KEYWORDS = c('thwart', 'dugout', 'sigma', 'precontact')),
  file2 = data.frame(KEYWORDS = c('newsom', 'site', 'date'))
)

# BIND THEM INTO A DATAFRAME AND RESHAPE TO DESIRED FORM
datdf <- plyr::ldply(datlist, function(x) data.frame(x, id = 1:NROW(x)))
reshape(datdf, timevar = '.id', direction = 'wide', sep = "_") 

   id KEYWORDS_file1 KEYWORDS_file2
1  1         thwart         newsom
2  2         dugout           site
3  3          sigma           date
4  4     precontact           <NA>
...