2013-03-14 3 views
0

Я довольно новичок в R, но, похоже, это конкретная проблема, к которой я не смог найти ответ.R-rbind транспонирование одной колонки матрицы

Моя программа читает в некоторых данных, то rbinds определенных столбцов этих данных к одному из нескольких кадров данных на основе вектора чисел столбцов я прохожу его, так что-то вроде этого:

filename <- c("vector", "full", "of", "filenames") 
colVal <- (32)  
InMat <- data.frame() 
for (i in 1:length(filename)){ 
    file <- read.table(filename[i], header=TRUE, fill=TRUE, stringsAsFactors=FALSE) 
    InMat <- rbind(InMat, file[c(2:dim(file)[1], colVal)]) 
    #...other matricies... 
} 

Моей проблема заключается в случае, когда имеется только один желаемый столбец, то есть colVal принимает одно значение. В этом случае я считаю, что InMat существенно переносится из того, что мне потребуется. Хуже того, когда я читаю файлы в mulitple, он привязывает транспонированный нужный столбец, поэтому я получаю количество строк, равное количеству файлов, которые я читаю, с таким количеством столбцов, сколько строк в каждом столбце каждого файла.

Похоже, что если имеется 2 желаемых столбца (то есть colVal принимает два или более значений), то он действует так, как я ожидаю (т.е. столбец считывается и сохраняется в InMat в качестве столбца, сохраняются столбцы из каждого дополнительного файла ниже).

Мой вопрос в том, почему rbind действует по-разному, когда ему передается только одно требуемое значение столбца, и если есть простой способ (читай, не добавляя какой-нибудь неуклюжий цикл if или для проверки), чтобы избежать этого?

Спасибо!

ответ

0

Короткий ответ: [.data.frame (оператор [ на кадры данных) по умолчанию преобразует вывод в минимально возможное измерение (через аргумент drop=TRUE). Если вы вытаскиваете только один столбец, то он преобразуется в вектор, который затем создает матрицу с другими векторами через rbind в матрицу. Когда вы извлекаете два или более столбца, вы получаете кадр данных, поэтому вывод rbind является фреймом данных.

Быстрое исправление, чтобы изменить эту строку:

InMat <- rbind(InMat, file[c(2:dim(file)[1], colVal)]) #old line 
InMat <- rbind(InMat, file[c(2:dim(file)[1], colVal),drop=FALSE]) #new line 

Более R-подобный способ кодирования это было бы использовать lapply и вызвать rbind один раз. Поскольку R назначается по копиям, растущие объекты путем повторного конкатенации/добавления довольно неэффективны (см. Второй круг R Inferno).

filename <- c("vector", "full", "of", "filenames") 
colVal <- (32)  
dfm <- lapply(filename, read.table 
    , header=TRUE, fill=TRUE, stringsAsFactors=FALSE) 
dfm <- lapply(dfm,`[`,colVal) 
dfm <- do.call(rbind,dfm) 

Если вы знаете позиции столбцов, которые вы хотите заранее извлечь, вы могли бы использовать colClasses аргумент read.table и пропустить чтение всей таблицы:

filename <- c("vector", "full", "of", "filenames") 
colVal <- 32 
cc <- rep.int("NULL",40) #where 40 is # of columns in table 
cc[colVal] <- NA 
dfm <- lapply(filename, read.table 
    , header=TRUE, fill=TRUE, colClasses=cc, stringsAsFactors=FALSE) 
dfm <- do.call(rbind,dfm) 
+0

Кажется хорошо работать, хотя по какой-то причине мой код работает медленнее –

+0

Какая часть делает ваш код медленнее? –

+0

Если я запустил код в консоли R GUI, похоже, что он замедляется при первом вызове lapply. Он останавливается на 2-5 секунд или около того. (FYI Я использую ваш второй предложенный бит кода). –

0

Когда вы берете только один столбец, он становится вектором. Было бы лучше, если бы вы просто приложили все значения в вектор вместо матрицы

InVec <- c() 
for (i in 1:length(filename)){ 
    file <- read.table(filename[i], header=TRUE, fill=TRUE, stringsAsFactors=FALSE) 
    InVec <- c(InVec, file[-1, colVal)]) 
    #...other matricies... 
} 

Использование с() будет намного быстрее, чем rbind а

+0

Я думаю, что я бегу в здесь возникают проблемы с выполнением действий над этими векторами. Поскольку я читаю в нескольких файлах, все из которых имеют разную длину, я получаю несогласованные номера строк и не могу печатать и т. Д. Любые мысли? –

+0

Какие действия вы выполняете? – LostLin

+0

Некоторые из матриц требуют столбца min/max, другие - и, наконец, все они должны быть записаны в файл csv. Данные полчаса и разделены между файлами по месяцам. Так что некоторые файлы 30 * 48, 29 * 48 и т. Д. ... –

Смежные вопросы