我有一个向量(称之为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
但这很笨拙,如果我想创建大量的列,那将会很乏味。如何保持矢量长度相同(或以另一种方式解决这个问题)?
答案 0 :(得分:2)
以下是使用do.call
和lapply
尝试执行的操作的循环版本:
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