首页 > 解决方案 > R合并两个不同长度的数据帧,重复较短的行,直到第一个值发生变化

问题描述

我想将两个不同大小的df合并在一起。两者都有时间戳,但时间戳不重叠。我可以很容易地将时间戳从小 df 获取到较大的 df,但我的目标是重复较小 df 的行,直到下一个时间戳和参数发生变化,如较小的 df 所示。演示[根据以下评论编辑]的最小可重现示例:

set.seed(123)
gratingspeed <- c(sample(c(-3:3), 10, replace=TRUE))
gratingfreq <- sample(c(-2, -1, 0.5, 0.5, 1, 2), 10, replace=TRUE)
timestamp <- runif(10, min=0, max=25)
timestamp[1] <- 0
stimuli <- data.frame(gratingspeed, gratingfreq, timestamp)
stimuli <- arrange(stimuli, stimuli$timestamp)
timemultiplier <- c(rep(c(-1,1), 5))
stimuli <- cbind(timemultiplier, stimuli)
stimuli$dfid <- row_number(stimuli$timestamp)

trackingx <- runif(25, min=0, max=800)
trackingy <- runif(25, min=0, max=800)
boutsuccess <- vector <- sample(c(rep(TRUE, 23), rep(FALSE, 2)), 25 ,replace = T)
timestamp <- c(1:25)
trackingdata <- cbind(trackingx, trackingy, boutsuccess, timestamp)
trackingdata <- as.data.frame(trackingdata)
trackingdata$dfid <- NA

我发现 merge(sort=FALSE) 是最好的方法,但我需要一个通用列来合并这些 df。我构建了一个 dfid 列,它充当此过程的索引,如下所示:

trialdummy <- stimuli
trialdummy[c(1:3)] <- NA  
names(trialdummy)[1:3] <- c("trackingx", "trackingy", "boutsuccess")
trialdata <- rbind(trialdummy, trackingdata)
trialdata <- trialdata %>%
  arrange(timestamp)

但是我需要重复 dfid 索引,直到值发生变化。也许涉及 rle()。对于构建正确的 dfid 列以便我可以使用 merge(sort=FALSE) 或合并两个原始 df 的更好方法的任何帮助将不胜感激。Tidyverse 的答案表示赞赏,但不是必需的。谢谢!

标签: rdataframemerge

解决方案


我想你需要tidyr::fill

library(tidyr)
trialdata %>% 
  fill(dfid, .direction = "down")
#    trackingx   trackingy boutsuccess timestamp dfid
# 1         NA          NA          NA  0.000000    1
# 2  721.83924 102.0253202           1  1.000000    1
# 3  552.56422 602.6462914           1  2.000000    1
# 4  636.37393 716.0362873           1  3.000000    1
# 5         NA          NA          NA  3.677841    2
# 6   19.69095 299.5702207           1  4.000000    2
# 7  382.23678 532.0921557           1  5.000000    2
# 8  606.76763  75.8725287           1  6.000000    2
# 9  173.12635 307.1757102           1  7.000000    2
# 10        NA          NA          NA  7.228993    3
# 11 254.54481 219.5069157           1  8.000000    3
# 12 185.30063 651.7120311           1  9.000000    3
# ...

如果您已经在使用dplyrbind_rows它是一种更灵活、更有效的替代rbind.


推荐阅读