Объединение списка data.frames с пересекающимися генами и избыточными столбцами в единый уникальный data.frame - PullRequest
0 голосов
/ 14 ноября 2018

У меня есть list из data.frame с. Некоторые из data.frame являются избыточными, и среди не избыточных строки (обозначенные столбцом id) не идентичны, но перекрываются:

set.seed(2)
ids.1.2 <- paste0("id",sample(30,10,replace = F))
ids.3.4 <- paste0("id",sample(30,20,replace = F))

df.1 <- data.frame(id = ids.1.2,matrix(rnorm(100),10,10,dimnames = list(NULL,paste0("s.1.2:",1:10))))
df.2 <- df.1
df.3 <- data.frame(id = ids.3.4,matrix(rnorm(300),20,15,dimnames = list(NULL,paste0("s.3.4:",1:15))))
df.4 <- df.3

df.list <- list(df.1, df.2, df.3, df.4)

Таким образом, в этом случае df.1 и df.2 идентичны, равно как и df.3 и df.4, и оба набора пересекаются на id s:

"id6"  "id21" "id17" "id5"  "id24" "id11" "id12

Существует ли purrr::reduce или аналогичный способ объединить этот список в один data.frame с уникальными столбцами и пересекающимися id х?

Я бы использовал:

purrr::reduce(df.list, dplyr::inner_join,by = "id")

Если все data.frame имеют уникальные столбцы. Но в моем случае использование этого добавляет .x, .y, ... достаточно к избыточным столбцам.

1 Ответ

0 голосов
/ 14 ноября 2018

Я не уверен, что это то, что вы, но я сначала удалил идентичные кадры данных, а затем объединил остальные.Это не очень хорошее решение, и вы можете настроить его здесь и там, но если я правильно понял, это даст вам желаемый результат.Возможно, вы захотите включить строку, которая удаляет идентичные комбинации в кадре данных combinations, чтобы вы могли быть уверены, что при удалении идентичных dfs из вашего списка ошибок не будет.

library(tidyr)
library(dplyr)

# create all possible combinations
names(df.list) <- 1:length(df.list)
combinations <- crossing(names(df.list), names(df.list))
colnames(combinations) <- c("v1", "v2")

# remove self-combinations
combinations <- combinations[!combinations$v1 == combinations$v2,]

# check which cases are identical
combinations$check <- sapply(1:nrow(combinations), function(x){combinations[x,] <- identical(df.list[[combinations$v1[x]]], df.list[[combinations$v2[x]]])})
combinations <- combinations[combinations$check == T,]

# remove identical cases
for(i in 1:length(df.list)){
  if(combinations$v1[i] == names(df.list)[i] & combinations$v1[i] %in% names(df.list)){df.list[i] <- NULL}

}

# combine dataframes
bind_rows(df.list)
...