Объединить фреймы данных в третьем измерении по именам строк / столбцов - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть произвольное количество фреймов данных с именами строк и столбцов.

Моя цель - объединить эти фреймы данных, используя имена строк / столбцов в качестве ключа соединения, в третьем измерении, т. Е. Я хочурезультатом будет именованный трехмерный массив.

Моя проблема в том, что я не хочу присоединяться к ним позиционно , но по именам строк / столбцов.

Iзнаю, что я могу использовать abind () для объединения массивов по любому желаемому измерению, но abind объединяет данные позиционно , а не по dimname.

В терминах SQL я хочуполное объединение с использованием имен строк / столбцов в качестве ключей объединения, но по третьему измерению.

Здесь у вас есть небольшой воспроизводимый пример только с двумя фреймами данных:

first <- data.frame(one=c(1,2), two=c(3,4), row.names = c("one", "two"))
second <- data.frame(one=c(10,20), three=c(50,60), row.names = c("one", "three"))
result <- someMagicFunction(first, second)

Мой желаемый вывод дляОбъект «result»:

result <- array(data=c(1, 2, NA, 3, 4, NA, NA, NA, NA,
                       10, NA, 20, NA, NA, NA, 50, NA, 60), 
                dim = c(3, 3, 2), 
                dimnames = list(
                  c("one", "two", "three"),
                  c("one", "two", "three"),
                  c("first", "second")))
> result
, , first

      one two three
one     1   3    NA
two     2   4    NA
three  NA  NA    NA

, , second

      one two three
one    10  NA    50
two    NA  NA    NA
three  20  NA    60

Я сам написал функцию для выполнения задачи, но я хотел бы знать, есть ли уже встроенная функция для этого.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 12 сентября 2018

Непонятно о «массиве». Я бы решил это так:

Если вы ищете быстрый , базовый и элегантный решение:

данные:

first <- data.frame(one=c(1,2), two=c(3,4), row.names = c("one", "two"))
second <- data.frame(one=c(10,20), three=c(50,60), row.names = c("one", "three"))

l <- list(first, second)

Код:

dn <- unique(c(sapply(l, names)))

model<-as.data.frame(structure(rep(NA,length(dn)^2), .Dim = c(length(dn), length(dn)), .Dimnames = list(dn, dn)))

lapply(l, function(el){model[names(el),names(el)] <- el;model})

результат:

[[1]]
      one two three
one     1   3    NA
two     2   4    NA
three  NA  NA    NA

[[2]]
      one two three
one    10  NA    50
two    NA  NA    NA
three  20  NA    60
0 голосов
/ 12 сентября 2018
library(abind)
library(magrittr)

in.dfs <- list(first, second)

cols <- unique(unlist(lapply(in.dfs, names)))
rows <- unique(unlist(lapply(in.dfs, rownames)))

allNA <- 
  matrix(NA, length(cols), length(rows)) %>% 
    `colnames<-`(cols) %>% 
    `rownames<-`(rows)

lapply(in.dfs, function(df){
  allNA[rownames(df), names(df)] <- as.matrix(df)
  allNA
}) %>% 
  list(along = 3) %>% 
  do.call(what = abind)

Результат

# , , 1
# 
#       one two three
# one     1   3    NA
# two     2   4    NA
# three  NA  NA    NA
# 
# , , 2
# 
#       one two three
# one    10  NA    50
# two    NA  NA    NA
# three  20  NA    60
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...