如何创建标准大小的矢量,以便将它们添加到数据框中?

时间:2013-04-03 19:15:26

标签: r

我有一个向量(称之为t1),带有一系列观察结果。我想通过从t1弹出第一个观察来创建一组新的向量(对于后续的近拷贝,依此类推)。但是我希望保持矢量的长度相同,以便稍后将它们添加到数据帧中。

我能够按如下方式工作:

t1 <- c(1, 2, 3)
t2 <- t1[-1]
t3 <- t2[-1]

t2[length(t2)+1] <- 0

t3[length(t3)+1] <- 0
t3[length(t3)+1] <- 0

t.all <- cbind(as.data.frame(t1), as.data.frame(t2), as.data.frame(t3))

t.all

  t1 t2 t3
1  1  2  3
2  2  3  0
3  3  0  0

但这很笨拙,如果我想创建大量的列,那将会很乏味。如何保持矢量长度相同(或以另一种方式解决这个问题)?

5 个答案:

答案 0 :(得分:2)

以下是使用do.calllapply尝试执行的操作的循环版本:

cbind(t1,do.call(cbind,lapply(seq_along(t1)-1,
                     function(x)c(tail(t1,-x),rep(0,x)))))


    t1    
[1,]  1 2 3
[2,]  2 3 0
[3,]  3 0 0

答案 1 :(得分:1)

这是使用矢量索引的另一种方式:

t1 <- (2,5,3)
mm <- do.call(rbind, lapply(seq_along(t1), function(x) t1[x:length(t1)][1:length(t1)]))
#      [,1] [,2] [,3]
# [1,]    2    5    3
# [2,]    5    3   NA
# [3,]    3   NA   NA

mm[is.na(mm)] <- 0
#      [,1] [,2] [,3]
# [1,]    2    5    3
# [2,]    5    3    0
# [3,]    3    0    0

不使用apply系列的另一种方式:

t1 <- c(2,5,4,6)
len <- length(t1)
matrix(t1[outer(1:len, 0:(len-1), '+')], ncol=len)

#      [,1] [,2] [,3] [,4]
# [1,]    2    5    4    6
# [2,]    5    4    6   NA
# [3,]    4    6   NA   NA
# [4,]    6   NA   NA   NA

答案 2 :(得分:1)

> t.all <- sapply(0:2, function(x) c( t1[(x+1):3], rep(0,x) ) )
> t.all
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    2    3    0
[3,]    3    0    0

如果你需要它是一个data.frame,那么首先构建一个矩阵然后在最终结果周围包裹as.data.frame会更有效率。

答案 3 :(得分:0)

如何根据需要回收t1来逐行创建矩阵:

tmat <-cbind(t1,t1,t1,t1,....) # as many as needed

然后只使用矩阵三角函数

newmat<- tmat * upper.tri(tmat,diag=TRUE) 

这与您的示例相比有偏差,但每行包含相同的信息。

答案 4 :(得分:0)

其他大多数答案都专注于创建最终的data.frame。如果这是你的最终目标,那么他们提供了很好的方法。相反,这个答案只关注你如何关闭第一个元素并保留长度的问题。为了保持整洁,最好在一个功能中完成整个过程。

shift <- function(tx) {append(tx[-1],0)}

然后你可以

t1 <- c(1, 2, 3)
t2 <- shift(t1)
t3 <- shift(t2)

t.all <- data.frame(t1, t2, t3)

给你的结果与你相同。

> t.all
  t1 t2 t3
1  1  2  3
2  2  3  0
3  3  0  0

如果要将此函数与循环结构组合以创建data.frame,最简单的方法是首先查看矩阵。

t.all <- matrix(t1, nrow=length(t1), ncol=length(t1))
lapply(seq(length=length(t1))[-1], function(i) {
  t.all[,i] <<- shift(t.all[,(i-1)])
})
t.all <- as.data.frame(t.all)

提供相同的data.frame,但列名略有不同

> t.all
  V1 V2 V3
1  1  2  3
2  2  3  0
3  3  0  0