У меня есть list
из data.frame
с (в этом примере только 2):
set.seed(1)
df1 <- data.frame(id = sample(LETTERS,50,replace=T), val = rnorm(50), val1 = rnorm(50), stringsAsFactors = F)
df2 <- data.frame(id = sample(LETTERS,30,replace=T), val = rnorm(30), val2 = rnorm(30), stringsAsFactors = F)
df.list <- list(df1,df2)
Я хочу join
их в один data.frame
только подмножеством имен общих столбцов, в данном случае id
.
Если я использую:
library(dplyr)
df <- df.list %>% purrr::reduce(dplyr::inner_join,by="id")
Имена общих столбцов, к которым я не присоединяюсь, видоизменяются с помощью x
и y
:
id val.x val1 val.y val2
1 G -0.05612874 0.2914462 2.087167 0.7876396
2 G -0.05612874 0.2914462 -0.255027 1.4411577
3 J -0.15579551 -0.4432919 -1.286301 1.0273924
На самом деле, для имен общих столбцов, к которым я не присоединяюсь, достаточно выбрать их из одного элемента data.frame в списке - независимо от того, существуют ли они в WRT к объединенному id
.
Я не знаю заранее названий этих общих столбцов, но это не сложно выяснить:
например:.
df.list.colnames <- unlist(lapply(df.list,function(l) colnames(l %>% dplyr::select(-id))))
df.list.colnames <- table(df.list.colnames)
repeating.colnames <- names(df.list.colnames)[which(df.list.colnames > 1)]
Что затем позволит мне отделить их от data.frame
в list
:
repeating.colnames.df <- do.call(rbind,lapply(df.list,function(r) r %>% dplyr::select_(.dots = c("id",repeating.colnames)))) %>%
unique()
Затем я могу присоединиться к списку data.frame
с исключением этих столбцов:
А затем присоединитесь к ним, как указано выше:
for(r in 1:length(df.list)) df.list[[r]] <- df.list[[r]] %>% dplyr::select_(.dots = paste0("-",repeating.colnames))
df <- df.list %>% purrr::reduce(dplyr::inner_join,by="id")
А теперь мне осталось добавить к этому repeating.colnames.df
. Я не знаю ни одного join
в dplyr
, который не будет возвращать все комбинации между df
и repeating.colnames.df
, поэтому мне кажется, что все, что я могу сделать, это apply
над каждым df$id
, выбрать первое совпадение в repeating.colnames.df
и объедините результат с df
.
Есть ли что-нибудь менее громоздкое в этой ситуации?