希望通过对另一个数据帧的逻辑测试来优化一个数据帧中观察值的分箱?

Looking to optimize binning of observations in one dataframe with logical tests on another dataframe?

我是一名自学成才的编码员,正在寻找有关我用于分箱观察的算法的一些输入。我有 2 个数据框 df1 和 df2,带有一组观察值。我想根据事件发生的时间将一个时间序列中的事件关联到另一个时间序列。我尝试了几种不同的方法并最终得到了以下功能。

bin_observations <- function(df1, df2) {
  df1$beat.bin <- "NA"
  df1$beat.bin <- as.integer(df1$beat.bin)
  for (h in 1:nrow(df1)) {
    for(g in 1:nrow(df2)) {
      if (is.na(df1$beat.bin[h] == TRUE) & df1$SECONDS[h] <= df2$SECONDS[g]) {
          df1$beat.bin[h] <- df2$beat[g-1]
      }
    }
  }
  return(df1)
}

我要让函数按编写的方式工作的关键是引入一个逻辑测试来查看我正在写入的字段是否已经写入。在此之前,我对每个数据帧的值进行了一系列检查,以找到时间仓。那是一团乱七八糟的条件逻辑。

我的问题是,执行此类操作的更好方法是什么?另外,如果有人能指出一些我可以用来改进我的代码的好资源,我将不胜感激。

这是示例数据和示例输出。

df.1 <- data.frame( SECONDS = c(0.043, 0.169, 0.260, 0.384, 0.448, 0.869, 1.038, 1.560, 1.584, 1.644, 1.780, 2.772, 2.839, 3.080, 3.616))

df.2 <- data.frame( SECONDS = c(0.000, 0.510, 1.018, 1.518, 2.023, 2.531, 3.038, 3.546, 4.051, 4.569, 5.080, 5.595),
                   beat = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12))


----------


df.1 <- bin_observations(df1 = df.1, df2 = df.2 )


----------


> df.1

   SECONDS beat.bin
1    0.043        1
2    0.169        1
3    0.260        1
4    0.384        1
5    0.448        1
6    0.869        2
7    1.038        3
8    1.560        4
9    1.584        4
10   1.644        4
11   1.780        4
12   2.772        6
13   2.839        6
14   3.080        7
15   3.616        8

感谢您的任何建议或见解。

Base R 中的一种方法是使用 findInterval

data.frame(df.1,
           bin = findInterval(df.1$SECONDS, df.2$SECONDS))

#output
   SECONDS bin
1    0.043   1
2    0.169   1
3    0.260   1
4    0.384   1
5    0.448   1
6    0.869   2
7    1.038   3
8    1.560   4
9    1.584   4
10   1.644   4
11   1.780   4
12   2.772   6
13   2.839   6
14   3.080   7
15   3.616   8

如果 beat 列的编码不同:

df.2 <- data.frame(SECONDS = c(0.000,
                               0.510,
                               1.018,
                               1.518,
                               2.023,
                               2.531,
                               3.038,
                               3.546,
                               4.051,
                               4.569,
                               5.080, 
                               5.595),
                    beat = c("one",
                             "two",
                             "three",
                             "four",
                             "five",
                             "six",
                             "seven",
                             "eight",
                             "nine",
                             "ten",
                             "eleven",
                             "twelve"))

data.frame(df.1,
           bin = df.2$beat[findInterval(df.1$SECONDS, df.2$SECONDS)])
#output
   SECONDS   bin
1    0.043   one
2    0.169   one
3    0.260   one
4    0.384   one
5    0.448   one
6    0.869   two
7    1.038 three
8    1.560  four
9    1.584  four
10   1.644  four
11   1.780  four
12   2.772   six
13   2.839   six
14   3.080 seven
15   3.616 eight

数据:

dput(df.1)
structure(list(SECONDS = c(0.043, 0.169, 0.26, 0.384, 0.448, 
0.869, 1.038, 1.56, 1.584, 1.644, 1.78, 2.772, 2.839, 3.08, 3.616
), bin = c(1L, 1L, 1L, 1L, 1L, 2L, 3L, 4L, 4L, 4L, 4L, 6L, 6L, 
7L, 8L)), class = "data.frame", row.names = c(NA, -15L))
dput(df.2)
structure(list(SECONDS = c(0, 0.51, 1.018, 1.518, 2.023, 2.531, 
3.038, 3.546, 4.051, 4.569, 5.08, 5.595), beat = c(1, 2, 3, 4, 
5, 6, 7, 8, 9, 10, 11, 12)), class = "data.frame", row.names = c(NA, 
-12L))