Объединить фреймы данных со многими rownames == NA в R - PullRequest
1 голос
/ 29 мая 2020

Я хочу объединить следующие данные, data1 и data2.

> data1 
      A       B   C     D    E   F  
alpha "Jenna" "1" "50"  "60" "7" "1"
<NA>  NA      NA  "67"  "99" NA  NA 
<NA>  NA      NA  "55"  NA   NA  NA 
<NA>  NA      NA  "45"  NA   NA  NA 
beta  "Jenna" "1" "333" "89" "8" "1"
<NA>  NA      NA  "755" "74" NA  NA 
<NA>  NA      NA  "433" NA   NA  NA 
<NA>  NA      NA  "300" NA   NA  NA 

> data2
      A      B   C     D     E    F  
alpha "Lena" "1" "23"  "77"  "7"  "1"
<NA>  NA     NA  "67"  "103" NA   NA 
<NA>  NA     NA  "55"  NA    NA   NA  # note here only have 2 rows but 3 above
deta  "Lena" "1" "599" "9"   "76" "1" #note this one is deta not beta 
<NA>  NA     NA  "763" "88"  NA   NA 
<NA>  NA     NA  "1"   NA    NA   NA 
<NA>  NA     NA  "3"   NA    NA   NA 

в это: enter image description here

По сути, объедините df в соответствии с rownames. Если не существует, введите NA. * Я не хочу добавлять дополнительные имена (т.е. deta) вручную. У меня есть идея найти больший nrow (df), затем ... et c ??

> dput(data1)
structure(c("Jenna", NA, NA, NA, "Jenna", NA, NA, NA, "1", NA, 
NA, NA, "1", NA, NA, NA, "50", "67", "55", "45", "333", "755", 
"433", "300", "60", "99", NA, NA, "89", "74", NA, NA, "7", NA, 
NA, NA, "8", NA, NA, NA, "1", NA, NA, NA, "1", NA, NA, NA), .Dim = c(8L, 
6L), .Dimnames = list(c("alpha", NA, NA, NA, "beta", NA, NA, 
NA), c("A", "B", "C", "D", "E", "F")))
> dput(data2)
structure(c("Lena", NA, NA, "Lena", NA, NA, NA, "1", NA, NA, 
"1", NA, NA, NA, "23", "67", "55", "599", "763", "1", "3", "77", 
"103", NA, "9", "88", NA, NA, "7", NA, NA, "76", NA, NA, NA, 
"1", NA, NA, "1", NA, NA, NA), .Dim = 7:6, .Dimnames = list(c("alpha", 
NA, NA, "deta", NA, NA, NA), c("A", "B", "C", "D", "E", "F")))

1 Ответ

1 голос
/ 29 мая 2020

Нам может потребоваться развернуть строки в зависимости от наличия NA перед выполнением merge. Создайте индекс numeri c на основе элементов, отличных от NA (или используйте na.locf0 из zoo), split последовательность строк данных (или получите table из 'v1', 'v2' и возьмите max частоты), разверните строки, дополнив строки NA на основе 'l1', а затем выполните merge в row.names после заполнения rownames элементом, отличным от NA (na.locf0 ), измените имена строк вывода на replace, добавив некоторые элементы к NA

library(zoo)
v1 <- cumsum(!is.na(row.names(data1)))
v2 <- cumsum(!is.na(row.names(data2)))

lst1 <- split(seq_len(nrow(data1)), v1)
lst2 <- split(seq_len(nrow(data2)), v2)

l1 <- pmax(lengths(lst1), lengths(lst2))

dat1n <- do.call(rbind,  Map(function(x, y) data1[`length<-`(x, y), ], lst1, l1))
dat2n <- do.call(rbind,  Map(function(x, y) data2[`length<-`(x, y), ], lst2, l1))
row.names(dat1n) <- na.locf0(row.names(dat1n))
row.names(dat2n) <- na.locf0(row.names(dat2n))
out <-  merge(dat1n, dat2n, by = 'row.names', all = TRUE)

out1 <- as.matrix(out[-1])
row.names(out1) <- replace(out[,1], grepl("\\.\\d+$", out[,1]), NA)


out1
#      A.x     B.x C.x   D.x  E.x F.x A.y    B.y C.y   D.y   E.y  F.y
#alpha "Jenna" "1" "50"  "60" "7" "1" "Lena" "1" "23"  "77"  "7"  "1"
#<NA>  NA      NA  "67"  "99" NA  NA  NA     NA  "67"  "103" NA   NA 
#<NA>  NA      NA  "55"  NA   NA  NA  NA     NA  "55"  NA    NA   NA 
#<NA>  NA      NA  "45"  NA   NA  NA  NA     NA  NA    NA    NA   NA 
#beta  "Jenna" "1" "333" "89" "8" "1" NA     NA  NA    NA    NA   NA 
#<NA>  NA      NA  "755" "74" NA  NA  NA     NA  NA    NA    NA   NA 
#<NA>  NA      NA  "433" NA   NA  NA  NA     NA  NA    NA    NA   NA 
#<NA>  NA      NA  "300" NA   NA  NA  NA     NA  NA    NA    NA   NA 
#deta  NA      NA  NA    NA   NA  NA  "Lena" "1" "599" "9"   "76" "1"
#<NA>  NA      NA  NA    NA   NA  NA  NA     NA  "763" "88"  NA   NA 
#<NA>  NA      NA  NA    NA   NA  NA  NA     NA  "1"   NA    NA   NA 
#<NA>  NA      NA  NA    NA   NA  NA  NA     NA  "3"   NA    NA   NA 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...