Возьмите один столбец разной длины из многих файлов CSV и объедините его в одну матрицу в R

У меня есть 1000 файлов CSV с dfr.jstor.org с двумя столбцами, КЛЮЧЕВЫЕ СЛОВА и ВЕС. Длина каждого столбца варьируется от файла к файлу. Вот фрагмент одного 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 - пустая ячейка.

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


person Ben    schedule 09.11.2011    source источник
comment
Это довольно открытый конец. Как насчет того, чтобы начать использовать информацию из вопросов, на которые вы ссылались, а затем вернуться, когда у вас возникнет конкретная проблема?   -  person joran    schedule 10.11.2011
comment
Я не совсем уверен, с чего начать! Будем очень признательны за любые советы или подсказки.   -  person Ben    schedule 10.11.2011
comment
Попробуйте прочитать только два CSV в R и посмотрите, сможете ли вы их объединить.   -  person joran    schedule 10.11.2011
comment
Хорошо, я могу получить два файла csv и объединить их с помощью cbind и функции здесь. Куда дальше?   -  person Ben    schedule 10.11.2011


Ответы (3)


Чтобы сэкономить НЕМНОГО памяти / времени, вы можете изменить решение от @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. Последняя строка производит это вместо матрицы.

person Tommy    schedule 10.11.2011
comment
Это очень помогло, большое спасибо! Я просто взял ) из второй строки после [rowseq] и изменил KEYTERMS на "KEYTERMS", и он отлично справился со своей задачей. Очень поучительно, еще раз спасибо. - person Ben; 10.11.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)

может работать (изменить: добавлены отсутствующие скобки, NA_character_)

person Ben Bolker    schedule 09.11.2011
comment
Спасибо, я вижу, что вы там сделали с lapply и sapply, это полезно. Но я получаю это сообщение Error: unexpected '}' in: "c(x,rep(NA,len-length(x)) }" в конце блока ... - person Ben; 10.11.2011
comment
. @ Ben - добавьте закрывающую скобку, затем: c(x,rep(NA,len-length(x))) - person Tommy; 10.11.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>
person Ramnath    schedule 10.11.2011