2015-01-01 1 views
0

Скажем, у меня есть матрица A:Как комбинировать разные маты в соответствии с их именами строк?

rows.names Value 
---------------- 
man   NA 
woman  NA 
girl  NA 
boy   NA 
cat   NA 
dog   NA 

и еще несколько матриц (B, C, D, и т.д.), как следующее:

rows.names V1 
-------------- 
woman  3 
dog   5 


rows.names V2 
-------------- 
man   4 
woman  7 
cat   6 

rows.names V3 
--------------- 
boy   17 
cat   10 
dog   1 

И я хочу присоединиться к этим 4 по грести .names (замена отсутствующих данных на NA):

row.names Value V1 V2 V3 
-------------------------------- 
man   NA  NA 4 NA 
woman  NA  3 7 NA 
girl  NA  NA NA NA 
boy   NA  NA NA 17 
cat   NA  NA 6 10 
dog   NA  5 NA 1 

Как это можно сделать? Благодарю.

ответ

3

Ваше название говорит «матрицы», но ваш вопрос помечен data.frame, так что здесь подход предполагается, что вы имеете дело с data.frame с:

df1 <- data.frame(rn = c("man", "woman", "girl", "boy", "cat", "dog"), 
        Value = NA) 
df2 <- data.frame(rn = c("woman", "dog"), V1 = c(3, 5)) 
df3 <- data.frame(rn = c("man", "woman", "cat"), V2 = c(4, 7, 6)) 
df4 <- data.frame(rn = c("boy", "cat", "dog"), V3 = c(17, 10, 1)) 

library(reshape2) 
dcast(melt(mget(ls(pattern = "df\\d")), id.vars = "rn"), 
     rn ~ variable, value.var = "value") 
#  rn Value V1 V2 V3 
# 1 boy NA NA NA 17 
# 2 cat NA NA 6 10 
# 3 dog NA 5 NA 1 
# 4 girl NA NA NA NA 
# 5 man NA NA 4 NA 
# 6 woman NA 3 7 NA 

Общая идея заключается в том, чтобы использовать mget, чтобы захватить все из соответствующих объектов в list (вы можете сделать это вручную тоже, конечно). Затем используйте метод list для melt, чтобы объединить все в «длинный» data.frame. Затем его можно легко изменить, используя dcast.


подход похож (может быть, даже проще), если у вас есть матрицы:

m1 <- `rownames<-`(as.matrix(df1[-1]), df1[[1]]) 
m2 <- `rownames<-`(as.matrix(df2[-1]), df2[[1]]) 
m3 <- `rownames<-`(as.matrix(df3[-1]), df3[[1]]) 
m4 <- `rownames<-`(as.matrix(df4[-1]), df4[[1]]) 

dcast(melt(mget(ls(pattern = "m\\d"))), Var1 ~ Var2, value.var = "value") 
# Var1 Value V1 V2 V3 
# 1 man NA NA 4 NA 
# 2 woman NA 3 7 NA 
# 3 girl NA NA NA NA 
# 4 boy NA NA NA 17 
# 5 cat NA NA 6 10 
# 6 dog NA 5 NA 1 
+0

Спасибо! Кажется, я понимаю это :). –

2

Похоже, что это будет работать. Просто сопоставьте имена строк с матрицей значений, а затем замените их на подмножество. vapply упростит его до матрицы, чтобы мы могли cbind с основной матрицей.

mlist <- list(m2, m3, m4) 

newPart <- vapply(mlist, function(x) { 
     x[match(rownames(m1), rownames(x))] 
    }, numeric(nrow(m1))) 

cbind(m1, provideDimnames(newPart)) 
#  Value A B C 
# man  NA NA 4 NA 
# woman NA 3 7 NA 
# girl  NA NA NA NA 
# boy  NA NA NA 17 
# cat  NA NA 6 10 
# dog  NA 5 NA 1 
+0

Я думал о 'match', но было неясно, будет ли первая матрица содержать все имена розеток. Итак, я решил, что поеду на более предсказуемый маршрут. (+1) – A5C1D2H2I1M1N2O1R2T1

+0

@AnandaMahto - еще один приятный трюк, который я получил, что создает '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' Вы можете заменить одно NA более чем одним, а NA заполнить пробелы. 'replace (NA, c (2,5,6,9,10), LETTERS [1: 5])' –

+0

Единственный недостаток, возможно, не дает желаемой длины –

Смежные вопросы