объединить соответствующие столбцы в data.frame или data.table - PullRequest
8 голосов
/ 29 марта 2012

У меня есть следующие data.frames:

a <- data.frame(id = 1:3, v1 = c('a', NA, NA), v2 = c(NA, 'b', 'c'))
b <- data.frame(id = 1:3, v1 = c(NA, 'B', 'C'), v2 = c("A", NA, NA))
> a
  id   v1   v2
1  1    a <NA>
2  2 <NA>    b
3  3 <NA>    c
> b
  id   v1   v2
1  1 <NA>    A
2  2    B <NA>
3  3    C <NA>

примечание: Нет идентификаторов, для которых v1 или v2 определены в обеих таблицах; в каждом столбце есть только одно уникальное значение, отличное от NA, для каждого значения идентификатора

Я хотел бы объединить эти фреймы данных с соответствующими значениями "id":

ab <- merge(a, b, by = "id")

но я также хотел бы объединить два столбца v1 и v2, чтобы data.frame ab выглядел следующим образом:

ab <- data.frame(id = 1:3, v1 = c("a", "B", "C"), v2 = c("A", "b", "c"))

> ab
  id v1 v2
1  1  a  A
2  2  B  b
3  3  C  c

вместо этого я получаю это:

> merge(a, b, by = "id")
  id v1.x v2.x v1.y v2.y
1  1    a <NA> <NA>    A
2  2 <NA>    b    B <NA>
3  3 <NA>    c    C <NA>

было бы полезно иметь примеры с использованием data.frame и data.table, поэтому вот приведенные выше версии data.table:

A <- data.table(a, key = 'id')
B <- data.table(b, key = 'id')
A[B]

Ответы [ 2 ]

7 голосов
/ 29 марта 2012

Тип слияния, который вы укажете, вероятно, будет невозможен при использовании merge (с фреймами данных), хотя говорят, что обычно это приводит к ошибкам.

Вы также опускаете некоторые детали: всегда будутодно уникальное не NA значение в каждом столбце для каждого id значения?Если это так, это будет работать:

ab <- rbind(a,b)
> colFun <- function(x){x[which(!is.na(x))]}
> ddply(ab,.(id),function(x){colwise(colFun)(x)})
  id v1 v2
1  1  a  A
2  2  B  b
3  3  C  c

Аналогичная стратегия должна работать и с data.table с:

abDT <- data.table(ab,key = "id")
> abDT[,list(colFun(v1),colFun(v2)),by = id]
     id V1 V2
[1,]  1  a  A
[2,]  2  B  b
[3,]  3  C  c
4 голосов
/ 29 марта 2012

Если ваши данные так же просты, как и выше, ответ Джорана, вероятно, самый простой. Вот может подойти в базу:

a <- data.frame(id = 1:3, v1 = c('a', NA, NA), v2 = c(NA, 'b', 'c'))
b <- data.frame(id = 1:3, v1 = c(NA, 'B', 'C'), v2 = c("A", NA, NA))

decider <- function(x, y) factor(ifelse(is.na(x), as.character(y), as.character(x)))
data.frame(mapply(a, b, FUN = decider))

Если ваши данные имеют разные идентификаторы (некоторые перекрываются, а некоторые нет, то вот другой подход:

a <- data.frame(id = c(1,2,4,5), v1 = c('a', NA, "q", NA), v2 = c(NA, 'b', 'c', "e"))
b <- data.frame(id = 1:4, v1 = c(NA, "A", "C", 'B'), v2 = c("A", NA, "D", NA))

decider <- function(x, y) factor(ifelse(is.na(x), as.character(y), as.character(x)))

DF <- data.frame(mapply(a, b, FUN = decider))
DF2 <- rbind(b[!b$id %in% DF$id , ], DF)
DF2 <- DF2[order(DF2$id), ]
rownames(DF2) <- 1:nrow(DF2)
...