在条件下使用哪个功能转置列的一部分

问题描述 投票:0回答:1

假设我们有以下数据:

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函数的结果?

r performance dataframe transpose which
1个回答
0
投票

您可以使用一些向量化的技巧通过一次分配来完成此操作:

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))
© www.soinside.com 2019 - 2024. All rights reserved.