2012-03-21 2 views
11

Привет, У меня есть много файлов CSV для обработки. Каждый файл генерируется путем запуска алгоритма. Мои данные всегда имеет один ключ и значение, как это:Объединение кадров данных в R

csv1:

 index value 
    1  1  1 
    2  2  1 
    3  3  1 
    4  4  1 
    5  5  1 

csv2:

 index value 
1  4  3 
2  5  3 
3  6  3 
4  7  3 
5  8  3 

Теперь я хочу, чтобы объединить эти данные в формате CSV, например:

Если оба файла содержат идентичный ключ, например 5, результирующая строка должна содержать ключ как общий ресурс файлов (5), так и среднее значение обоих значений ((1 + 3)/2 = 2). Если только один файл содержит ключ (например, 2), эта строка просто добавляется в таблицу результатов (ключ = 2, значение = 1).

Что-то вроде этого:

 index value 
1  1  1 
2  2  1 
3  3  1 
4  4  2 (as (1+4)/2 = 2) 
5  5  2 (as (1+4)/2 = 2) 
6  6  3 
7  7  3 
8  8  3 

Сначала я думал, что rbind() делает работу, но это не агрегирует значения, только объединяющее данные. Как я могу достичь этого с помощью R?

+5

'rbind', то' aggregate' – James

+3

Вы должны, вероятно, просто сделать это двумя отдельными шагами - 1) Объединить значения в одну структуру (которую вы использовали с помощью rbind) и 2) Совокупность на основе индекса. Вы можете легко сделать шаг 2, используя что-то вроде ddply (из пакета plyr) или нарезать или заполнить. – Dason

+4

с использованием 'aggregate (. ~ Index, data = rbind (data1, data2), mean)' делает то, что я хочу, thx! –

ответ

13

Вот решение. Я придерживаюсь всех замечательных замечаний и надеюсь, что добавит ценность, показывая вам, как обрабатывать любое количество файлов. Я предполагаю, что у вас есть все ваши файлы csv в том же каталоге (my.csv.dir ниже).

# locate the files 
files <- list.files(my.csv.dir) 

# read the files into a list of data.frames 
data.list <- lapply(files, read.csv) 

# concatenate into one big data.frame 
data.cat <- do.call(rbind, data.list) 

# aggregate 
data.agg <- aggregate(value ~ index, data.cat, mean) 

Edit: обрабатывать обновленный вопрос в свой комментарий ниже:

files  <- list.files(my.csv.dir) 
algo.name <- sub("-.*", "", files) 
data.list <- lapply(files, read.csv) 
data.list <- Map(transform, data.list, algorithm = algo.name) 
data.cat <- do.call(rbind, data.list) 
data.agg <- aggregate(value ~ algorithm + index, data.cat, mean) 
+0

thx для этого приятного скрипта. Я попробую на следующей неделе! –

+0

У меня есть дополнение к этой проблеме. У меня есть несколько алгоритмов, создающих эти файлы csv. Поэтому мои имена файлов CSV выглядят следующим образом: 'algorithm1-values-run1.csv, algorithm1-values-run2.csv, algorithm2-values-run1.csv, algorithm2-values-run2.csv'. Теперь я хочу прочитать все CSV-файлы, но их агрегировать по алгоритму. Поэтому я создаю список списков или что-то вроде этого. Также он должен сохранять имена алгоритмов. –

+0

Я знаю, что прошло два года, но если вы все еще заинтересованы, я обработаю ваш дополнительный запрос. Пожалуйста, подумайте о принятии моего ответа. – flodel

0

То, что я понял из вопроса в том, что вы хотите получить список, который будет содержать списки data.frame файлов csv или файлов txt и суммировать их.

Создайте каталог и оставьте все файлы csv и txt в папке. Теперь запустите следующую команду, чтобы получить результат в списке.

л = list.files (шаблон = "CSV")

этот л объект будет содержать имена файлов CSV

м = Карта (read.csv, л)

Эта функция карты отображает функцию read.csv во все файлы csv, а объект m содержит файлы csv в виде data.frame в списке.

dat = do.вызов (rbind, м)

теперь называть библиотеки plyr

библиотека (plyr)

разреш = ddply (DAT, ~ индекс, обобщать, значение = среднее (значение))

этот рес объект будет содержать агрегированный значение

Я надеюсь, что это поможет вам получить результат желания.