在R中将不同长度的向量组合成数据框。

3

我有四个向量,分别是:

x1=letters[1:5]
x2=c("a","b","c")
x3=c("a","b","c","d")
x4=c("a","b","e")

实际上,我希望得到一个像这样的数据框架:
 data.frame(x1,x2=c("a","b","c",NA,NA),
            x3=c("a","b","c","d",NA),
           x4=c("a","b",NA,NA,"e"))
  x1   x2   x3   x4
1  a    a    a    a
2  b    b    b    b
3  c    c    c <NA>
4  d <NA>    d <NA>
5  e <NA> <NA>    e

有人可以帮我或给我一个指标函数吗?

4个回答

2
使用sqldf从x1连接的解决方案
   require(sqldf)

    x1 <- data.frame(x1)
    x2 <- data.frame(x2)
    x3 <- data.frame(x3)
    x4 <- data.frame(x4)

    x <- sqldf('select x1.x1, x2.x2, x3.x3, x4.x4
                from x1
                left join x2 on x1.x1 = x2.x2
                left join x3 on x1.x1 = x3.x3
                left join x4 on x1.x1 = x4.x4
               ')

非常感谢,你的回答提醒了我学习一些关于SQL操作的知识。 - chunjin

2

您可以执行以下操作:

ll = list(x1=x1, x2=x2, x3=x3, x4=x4)
x  = unique(unlist(ll))

data.frame(lapply(ll, function(y) ifelse(is.element(x,y),x,NA)))
#  x1   x2   x3   x4
#1  a    a    a    a
#2  b    b    b    b
#3  c    c    c <NA>
#4  d <NA>    d <NA>
#5  e <NA> <NA>    e

或者,这里有一种更简洁的方式:
library(reshape2)
dcast(stack(list(x1=x1, x2=x2, x3=x3, x4=x4)), values~ind, value.var='values')[-1]

2

我的“splitstackshape”包中有一个未导出的函数charMat,可能对类似这样的问题有用。

在这里,我将它与mget一起使用:

## library(splitstackshape) # not required since you'll be using ::: anyway...
data.frame(t(splitstackshape:::charMat(mget(ls(pattern = "x\\d")), mode = "value")))
#   X1   X2   X3   X4
# a  a    a    a    a
# b  b    b    b    b
# c  c    c    c <NA>
# d  d <NA>    d <NA>
# e  e <NA> <NA>    e

感谢您让我了解“mget”和“splitstackshape”包的知识。我正在学习如何使用mget。还有一个问题:为什么我需要使用splitstackshape:::charMat(mget(ls(pattern = "x\\d")), mode = "value"),而charMat(mget(ls(pattern = "x\\d")), mode = "value")告诉我“错误:找不到函数“charMat”?”我使用的是Win8.1 64位,R3.2.1版本。 - chunjin
我第一次听说splitstackshape包,not exported function,这意味着你应该使用splitstackshape:::charMat而不是直接调用它? - chunjin
@chunjin,是的。这意味着它不应该直接调用,而应使用“:::”进行调用。 - A5C1D2H2I1M1N2O1R2T1

1
这是一个解决方案:

require(zoo)
l<-lapply(list(x1,x2,x3,x4),function(x){zoo(x,x)})
result<-Reduce(merge,l)
colnames(result)<-paste0('x',1:4)

result
#   x1 x2   x3   x4  
# a a  a    a    a   
# b b  b    b    b   
# c c  c    c    <NA>
# d d  <NA> d    <NA>
# e e  <NA> <NA> e   

在这里,lapplyzoo组合将创建一个有序观测值列表。Reduce将连续应用merge到该列表中。最后一步是重命名结果的列。
如果您需要的输出是数据框,则还可以将result转换为数据框:
result<-as.data.frame(result)
rownames(result)<-NULL

result
#   x1   x2   x3   x4
# 1  a    a    a    a
# 2  b    b    b    b
# 3  c    c    c <NA>
# 4  d <NA>    d <NA>
# 5  e <NA> <NA>    e

请注意,如果您有向量x1x20,创建list(x1,x2,...)可能太长,因此您可以使用sapply(paste0('x',1:4),get)代替list(x1,x2,x3,x4)

sapply(paste0('x',1:4),get) 应该等于 mget(ls(pattern = "x\\d")),谢谢,我从你的帮助中学到了很多。 - chunjin
@chunjin:确实,我忘记了mget - etienne
这是我在stackoverflow上发布的第一个问题,非常兴奋,希望你们中的许多人能够帮助我解决这个问题,谢谢。 - chunjin
我投了票,因为我是stackoverflow的新手,只有在我获得15分后才能呈现投票结果。 - chunjin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接