2016-04-19 4 views
1

У меня 4 dataframes в списке L, как показано ниже:союз кадра данных в R

L[[1]]: 

V1 V2 
B C 
A B 
Z B 

L[[2]]: 

V1 V2 
B D 
A B 
Z B 

L[[3]]: 

V1 V2 
Z Y 
X Z 
N Z 

L[[4]]: 

V1 V2 
Z J 
X Z 
N Z 

Это приходят из графа с головкой C, D, Y, и J. Очевидно, С и D является из того же графика, то есть Y и J. Как слить C с D и Y с J, учитывая, что эти фреймы данных находятся в списке L?

То, что я думаю, состоит в том, чтобы перебирать список и попарно сравнивать. Если dfx пересекаются с dfy-слиянием. Кто-нибудь может помочь с R-кодом?

Edit: То, что я имею в виду, как это: Получить первый элемент, по сравнению с второй, если все в порядке, сливались и сохранить первый элемент, удалить второй элемент, переходим к следующему элементу до последнего. Повторяйте, пока оставшийся элемент не будет удален. При этом список будет состоять из оставшегося элемента, который был объединен. Кто-нибудь знает, как реализовать это в коде? Ожидаемый результат:

L[[1]]: 

V1 V2 
B C 
B D 
A B 
Z B 

L[[2]]: 

V1 V2 
Z Y 
Z J 
X Z 
N Z 
+0

Каков ожидаемый результат? – akrun

+0

Я ожидаю список слитых. В примере, который я дал, он будет списком с двумя элеменями, объединенными с C и D, а другой будет объединен с D и Y. – Bharata

+0

Возможно, 'Reduce (function (...) merge (..., by = "V1"), list (mget (paste0 ("df", 1: 4)))) ' – akrun

ответ

0

Может быть, это подход к решению для вас?

# create list of data.frames 
ld <- list(
    data.frame(V1 = c("B","A","Z"), V2 = c("C","B","B")), 
    data.frame(V1 = c("B","A","Z"), V2 = c("D","B","B")), 
    data.frame(V1 = c("Z","X","N"), V2 = c("Y","Z","Z")), 
    data.frame(V1 = c("Z","X","N"), V2 = c("J","Z","Z")) 
) 
# suggested solution 
union_ld <- data.table::rbindlist(ld) 
unique(union_ld) 

Результаты:

V1 V2 
1: B C 
2: A B 
3: Z B 
4: B D 
5: Z Y 
6: X Z 
7: N Z 
8: Z J 

Update 1

Быстрый хак: два кадра данных в списке в соответствии с просьбой ОП. Согласно комментарию OP, порядок строк в каждом кадре данных результата не имеет значения.

list(
    unique(data.table::rbindlist(ld[1:2])), 
    unique(data.table::rbindlist(ld[3:4])) 
) 

приводит:

[[1]] 
    V1 V2 
1: B C 
2: A B 
3: Z B 
4: B D 

[[2]] 
    V1 V2 
1: Z Y 
2: X Z 
3: N Z 
4: Z J 

Предлагаемое решение объединяет в себе первые два кадра данных в списке в один кадр данных, удаляет повторяющиеся строки. Это повторяется для последних двух кадров данных в списке. Затем результирующие кадры данных снова объединяются в список.

Update 2

Это решение использует rbindlist из пакета data.table. Если вам не нравится это, то результат может быть возвращен в качестве «чистые» кадров данных, как этот

library(data.table) 
list(
    setDF(unique(rbindlist(ld[1:2]))), 
    setDF(unique(rbindlist(ld[3:4]))) 
) 

Update 3

Согласно комментарию OP там больше фреймов данных, которые должны быть объединены в несколько групп.

# set up a list of vectors of numbers of data.frames to combine 
dfs_to_combine <- list(c(1:2), c(3:4)) 
dfs_to_combine 

[[1]] 
[1] 1 2 

[[2]] 
[1] 3 4 

# now, combine data.frames as specified 
library(data.table) 
lapply(dfs_to_combine, function(x) setDF(unique(rbindlist(ld[x])))) 

[[1]] 
    V1 V2 
1 B C 
2 A B 
3 Z B 
4 B D 

[[2]] 
    V1 V2 
1 Z Y 
2 X Z 
3 N Z 
4 Z J 

Это просто, чтобы воспроизвести ваш первоначальный пример. Если вы хотите поменять друг друга по-разному, например,

dfs_to_combine <- list(c(1), c(2, 4), c(3)) 
+0

Результат должен иметь список с 2 элементами, как я выше. – Bharata

+0

@Bharata Соответствует ли порядок результатов? – Uwe

+0

Нет, порядок не вызывает беспокойства. – Bharata

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