[英]How can I create vectors of a standard size so I can add them to a data frame?
I have a single vector (call it t1) with a series of observations. 我有一个向量(称它为t1),具有一系列观察结果。 I want to create a set of new vectors by popping the first observation from t1 (and so on for subsequent near-copies). 我想通过从t1弹出第一个观察值来创建一组新矢量(以此类推,随后进行近拷贝)。 But I want to keep the vectors the same length so I can add them to a data frame later. 但是我想让向量保持相同的长度,以便以后可以将它们添加到数据帧中。
I was able to make it work as follows: 我能够使其工作如下:
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
But this is clumsy and it's going to be tedious if I want to create a large number of columns. 但这很笨拙,如果我要创建大量列,这将很乏味。 How can I keep the vectors the same length (or solve this problem another way)? 如何使向量保持相同的长度(或以其他方式解决此问题)?
Here a loop version of what you try to do , uding do.call
and lapply
: 这是您尝试执行的循环版本,如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
Here's another way using vector indexing: 这是使用向量索引的另一种方法:
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
Another way without using apply
family: 不使用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
> 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
If you need it to be a data.frame it would be a lot more efficient to build as a matrix first and then wrap as.data.frame
around the final result. 如果您需要将其作为data.frame,则首先将其构建为矩阵,然后将as.data.frame
包裹在最终结果周围会更有效率。
How about creating a matrix row-by-row, by recycling t1
as desired: 如何根据需要回收t1
来逐行创建矩阵:
tmat <-cbind(t1,t1,t1,t1,....) # as many as needed
Then just use a matrix triangle function 然后只需使用矩阵三角函数
newmat<- tmat * upper.tri(tmat,diag=TRUE)
That's offset from your sample, but contains the same info per row. 这与您的示例有偏差,但每行包含相同的信息。
Most of the other answers focus on creating the final data.frame. 其他大多数答案都集中在创建最终的data.frame上。 If that is your ultimate goal, then they provide good approaches. 如果那是您的最终目标,那么他们提供了很好的方法。 This answer instead focuses narrowly on your question of how to take the first element off and preserve the length. 相反,此答案仅关注您的问题,即如何删除第一个元素并保留长度。 In order to keep things tidy, it is best to do the whole thing in one function. 为了使事情整洁,最好将整个事情放在一个功能中。
shift <- function(tx) {append(tx[-1],0)}
Then you can have 那你可以
t1 <- c(1, 2, 3)
t2 <- shift(t1)
t3 <- shift(t2)
t.all <- data.frame(t1, t2, t3)
which gives you the same result you had. 这会给您与您相同的结果。
> t.all
t1 t2 t3
1 1 2 3
2 2 3 0
3 3 0 0
If you want to combine this function with a looping construct to create the data.frame, it is easiest to go through a matrix first. 如果要将此函数与循环结构结合在一起以创建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)
which gives the same data.frame, but with slightly different column names 给出相同的data.frame,但列名稍有不同
> t.all
V1 V2 V3
1 1 2 3
2 2 3 0
3 3 0 0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.