#r #dataframe #merge
Вопрос:
У меня есть около 100 фреймов данных, которые разделены по строкам.имена. Мне нужно объединить их все в одну таблицу, но есть некоторые недостатки, поэтому есть разные длины. У меня есть настроенные тестовые фреймы данных, такие как:
df1 = data.frame(row.names=c("chr1","chr2","chr3","chr4","chr5"),v1=c(10,43,1,44,598))
df2 = data.frame(row.names=c("chr1","chr2","chr4","chr5","chr6","chr7"),v2=c(6,64,21,98,10,20))
df3 = data.frame(row.names=c("chr2","chr3","chr4","chr5","chr6","chr7"),v3=c(20,30,40,50,60,70))
> df1
v1
chr1 10
chr2 43
chr3 1
chr4 44
chr5 598
> df2
v2
chr1 6
chr2 64
chr4 21
chr5 98
chr6 10
chr7 20
> df3
v3
chr2 20
chr3 30
chr4 40
chr5 50
chr6 60
chr7 70
Желаемый результат был бы:
v1 v2 v3
chr1 10 6 NA
chr2 43 64 20
chr3 1 NA 30
chr4 44 21 40
chr5 598 98 50
chr6 NA 10 60
chr7 NA 20 70
Итак, какой-то способ объединить df1, df2, df3,…, dfn.
Ответ №1:
Мы могли бы собрать все наборы данных в a list
и использовать merge
с Reduce
указанием в by
качестве нового столбца, созданного из имен строк
lst1 <- lapply(mget(ls(pattern = '^df\d
-выход
out
v1 v2 v3
chr1 10 6 NA
chr2 43 64 20
chr3 1 NA 30
chr4 44 21 40
chr5 598 98 50
chr6 NA 10 60
chr7 NA 20 70
Или использовать tidyverse
с full_join
после создания столбца имен строк с rownames_to_column
(из tibble
)
library(dplyr)
library(tibble)
library(purrr)
mget(ls(pattern = '^df\d
Комментарии:
1. @akrun можно немного упростить с помощью
list(df1, df2, df3) %>% map(rownames_to_column) %>% reduce(full_join) %>% select(-rowname)
2. Блестяще, теперь работает с вашим редактированием. Спасибо @akrun!!
)), (x)
transform(x, rn =row.names(x)))
out <- Reduce(function(...) merge(..., by = 'rn', all = TRUE),
lst1)
row.names(out) <- out[[1]]
out <- out[-1]
-выход
Или использовать tidyverse
с full_join
после создания столбца имен строк с rownames_to_column
(из tibble
)
Комментарии:
1. @akrun можно немного упростить с помощью
list(df1, df2, df3) %>% map(rownames_to_column) %>% reduce(full_join) %>% select(-rowname)
2. Блестяще, теперь работает с вашим редактированием. Спасибо @akrun!!
)) %>%
map(~ .x %>%
rownames_to_column('rn')) %>%
reduce(full_join, by = 'rn') %>%
column_to_rownames("rn")
v1 v2 v3
chr1 10 6 NA
chr2 43 64 20
chr3 1 NA 30
chr4 44 21 40
chr5 598 98 50
chr6 NA 10 60
chr7 NA 20 70
Комментарии:
1. @akrun можно немного упростить с помощью
list(df1, df2, df3) %>% map(rownames_to_column) %>% reduce(full_join) %>% select(-rowname)
2. Блестяще, теперь работает с вашим редактированием. Спасибо @akrun!!
)), (x)
transform(x, rn =row.names(x)))
out <- Reduce(function(…) merge(…, by = ‘rn’, all = TRUE),
lst1)
row.names(out) <- out[[1]]
out <- out[-1]-выход
Или использовать tidyverse
с full_join
после создания столбца имен строк с rownames_to_column
(из tibble
)
Комментарии:
1. @akrun можно немного упростить с помощью
list(df1, df2, df3) %>% map(rownames_to_column) %>% reduce(full_join) %>% select(-rowname)
2. Блестяще, теперь работает с вашим редактированием. Спасибо @akrun!!