假设我们有以下数据:
X Y
6
1
2
2
1 1
8
3
4
1
1 2
我想将其转换为:
X Y Y-1 Y-2 Y-3
6
1
2
2
1 1 2 2 1
8
3
4
1
1 2 1 4 3
即:对于具有X=1
的行-取3个先前的Y
值并将它们附加到此行。
我用循环将其“强加”:
namevector <- c("Y-1", "Y-2", "Y-3")
mydata[ , namevector] <- ""
for(i in 1:nrow(mydata)){
if(mydata$X[i] != ""){mydata[i,3:5] <- mydata$Y[(i-1):(i-3)]}
}
但是对于我的〜300k点的数据集来说太慢了-大约10分钟。
然后我找到了一个类似问题的帖子,他们提出了which
函数,该函数将时间缩短为可忍受的1-2分钟:
namevector <- c("Y-1", "Y-2", "Y-3")
mydata[ , namevector] <- ""
trials_rows <- which(mydata$X != "")
for (i in trials_rows) {mydata[i,3:5] <- mydata$Y[(i-1):(i-3)]}
但是考虑到which
不到一秒钟-我相信我可以以某种方式将which
与某种转置功能结合起来,但我无法解决。
我有一个大数据框(约30万行),而约6k行具有此“ X”值。
是否有一种快速简便的方法来快速完成此任务,而不是遍历which
函数的结果?
您可以使用一些向量化的技巧通过一次分配来完成此操作:
mydata[trials_rows, namevector] <- mydata$Y[trials_rows - rep(1:3,each=length(trials_rows))]
mydata
# X Y Y-1 Y-2 Y-3
#1 NA 6
#2 NA 1
#3 NA 2
#4 NA 2
#5 1 1 2 2 1
#6 NA 8
#7 NA 3
#8 NA 4
#9 NA 1
#10 1 2 1 4 3
[基本上,取trials_rows
中的每一行,使用矢量减法向后看三行,然后覆盖行中trials_rows
和列中namevector
的组合。
此处使用可复制的示例:
mydata <- structure(list(X = c(NA, NA, NA, NA, 1L, NA, NA, NA, NA, 1L),
Y = c(6L, 1L, 2L, 2L, 1L, 8L, 3L, 4L, 1L, 2L)), class = "data.frame", row.names = c(NA,
-10L))