Объедините множество R фреймов данных по строкам.имена с различной длиной

#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!!