2016-03-04 3 views
0

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

< файлов - list.files ("путь", шаблон = "TXT.", Ignore.case = T)

for(i in 1:length(files)) 
{ 
    data <- fread(files[i], header=T) 

    # Merge 
    mydata <- merge(mydata, data, by="ID", all.x=TRUE) 

    rm(data) 
} 

"MYDATA" выглядит следующим образом (упрощенно):

ID x1 x2 
1 2 8 
2 5 5 
3 4 4 
4 6 5 
5 5 8 

"данные" выглядит следующим образом (около 600 файлов, в общем 100GB). Пример 2 (отдельных) файлов. Интегрируя все в 1 было бы невозможно (слишком большой):

ID x3 
1 8 
2 4 

ID x3 
3 4 
4 5 
5 1 

Когда я запускаю мой код я получаю следующий набор данных:

ID x1 x2 x3.x x3.y 
1 2 8 8  NA 
2 5 5 4  NA 
3 4 4 NA  4 
4 6 5 NA  5 
5 5 8 NA  1 

То, что я хотел бы получить это:

ID x1 x2 x3 
1 2 8 8 
2 5 5 4 
3 4 4 4 
4 6 5 5 
5 5 8 1 

ID уникальны (никогда не дублирует более 600 файлов).

Любая идея о том, как достичь этого как можно более эффективно.

+0

Вы пытаетесь объединить все текстовые файлы в один текстовый файл? Если идентификатор уникален, почему бы не использовать 'rbind' или' cbind' для присоединения к ним вместо слияния? – user5249203

+0

Я не думаю, что есть функция, которая «сливается» так, как вы хотите, для вашей структуры данных. Возможно, нам придется написать его. Ваш файл 'data' не обязательно всегда содержит только столбец« x3 »? – Vlo

+0

данные всегда точные, 1 столбец «ID», 1 столбец «x3». У меня только больше идентификаторов в отдельных файлах данных, чем в mydata – research111

ответ

4

Это лучше подходит как комментарий, но я не могу комментировать.

Не было бы лучше перестроить вместо слияния? Кажется, это то, что вы хотите усмирить.

Set fill аргумент TRUE, чтобы заботиться о различных номеров столбцов:

asd <- data.table(x1 = c(1, 2), x2 = c(4, 5)) 
a <- data.table(x2 = 5) 
rbind(asd, a, fill = TRUE) 

    x1 x2 
1: 1 4 
2: 2 5 
3: NA 5 

ли это с data, а затем сливаются в mydata по ID.

Обновление для комментариев

files <- list.files("path", pattern=".TXT", ignore.case=T) 

ff <- function(input){ 
    data <- fread(input) 
} 

a <- lapply(files, ff) 
library(plyr) 
binded.data <- ldply(a, function(x) rbind(x, fill = TRUE)) 

Таким образом, это создает функцию для чтения файлов и толкает его к lapply, так что вы получите список, содержащий все ваши data файлов, каждый на своем dataframe.

С ldply от plyr rbind все dataframes в один информационный кадр.

Не трогайте mydata.

binded.data <- data.table(binded.data, key = ID) 

В зависимости от вашего mydata вы будете выполнять различные merge команды. См: https://rstudio-pubs-static.s3.amazonaws.com/52230_5ae0d25125b544caab32f75f0360e775.html

Update 2

files <- list.files("path", pattern=".TXT", ignore.case=T) 

ff <- function(input){ 
data <- fread(input) 
# This keeps only the rows of 'data' whose ID matches ID of 'mydata' 
data <- data[ID %in% mydata[, ID]] 
} 

a <- lapply(files, ff) 
library(plyr) 
binded.data <- ldply(a, function(x) rbind(x, fill = TRUE)) 

Update 3

Вы можете добавить cat увидеть файл функция читает прямо сейчас. Таким образом, вы можете видеть, после какого файла у вас заканчивается память. Это будет указывать на то, сколько файлов вы можете прочитать за один раз.

ff <- function(input){ 
# This will print name of the file it is reading now 
cat(input, "\n") 
data <- fread(input) 
# This keeps only the rows of 'data' whose ID matches ID of 'mydata' 
data <- data[ID %in% mydata[, ID]] 
} 
+0

Извините, я не уверен, правильно ли я это понимаю. Вы имеете в виду rbind все отдельные «данные»? Я пробовал rbind mydata и данные в цикле, но это не работает. – research111

+0

См. Обновление по ответе. – Jav

+0

Это работает на примере, но это не работает с моими данными. Невозможно получить 1 таблицу данных для всех моих файлов данных (= 100 ГБ), я столкнулся с проблемами памяти. Можно ли последовательно объединиться (так что для каждой «данных» с «mydata»), поскольку mydata существенно меньше. Или добавьте только наблюдения, которые соответствуют «mydata» в этой binded.data – research111