2012-01-05 9 views
5

У меня есть проблема, когда объединение следующих векторов, включенных в список:Как объединить векторы с разной длиной в списке в R?

x <- list(as.numeric(c(1,4)),as.numeric(c(3,19,11))) 
names (x[[1]]) <- c("species.A","species.C") 
names (x[[2]]) <- c("species.A","species.B","species.C") 

, который дает следующий список:

 
>x 
>[[1]] 
>species.A species.C 
>   1   4 
>[[2]] 
>species.A species.B species.C 
>  3  19  11 

сочетая их с помощью функции do.call: y<- do.call(cbind,x)

дает:

 
>y 
>    [,1] [,2] 
> species.A 1 3 
> species.B 4 19 
> species.C 1 11 

в то время как я хотел бы получить это:

 
>    [,1] [,2] 
> species.A 1 3 
> species.B NA 19 
> species.C 4 11 

ответ

4

Вы должны дать R немного больше помощи, путем получения конкретных векторов, все той же длины, что вы в конечном итоге хотите cbind вместе. В противном случае (как вы видели) R использует свои обычные правила утилизации для заполнения матрицы.

попробовать что-то вроде этого:

spp <- paste("species", c("A", "B", "C"), sep=".") 

x2 <- lapply(x, FUN=function(X) X[spp]) 
mat <- do.call("cbind", x2) 
row.names(mat) <- spp 

mat 
      [,1] [,2] 
species.A 1 3 
species.B NA 19 
species.C 4 11 

EDIT: Как Брайан упоминает в комментариях, это может быть немного более компактный (но за счет некоторой дискретностью). Какой из них вы используете, это только вопрос вкуса:

mat <- do.call("cbind", lapply(x, "[", spp)) 
row.names(mat) <- spp 
+0

Могли бы в строке назначение x2, и упростить его как 'do.call (cbind, lapply (x, '[', spp))' –

+0

Я вырвал задание и сделал определение FUN более явным для ясности, так как я считаю справедливым заключить, что OP относительный новичок. Но да, это все можно было сделать в одной строке. На самом деле, я мог бы также добавить это как быстрое редактирование. Благодарю. –

+0

Довольно разумно; Я просто указывал на альтернативу. –

5

Похоже, вы на самом деле пытаетесь слить. Таким образом, будет работать merge. Вам просто нужно сказать, чтобы он слился с именами и сохранил все строки.

do.call(merge, c(x, by=0, all=TRUE)) # by=0 and by="row.names" are the same 

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

1
merge(x = x[[1]], y = x[[2]], by = "names", all.y = TRUE) 
+1

Привет и добро пожаловать в SO. Это очень хорошая практика, чтобы добавить небольшое объяснение к коду только для ответов. – Fluffeh