首页 > 解决方案 > R-根据另一个数据框中的值在数据框中创建值的问题

问题描述

我有 2 个数据框。首先,我称之为“tableA”,它有一个开始时间、停止时间和与之相关的数字(还有更多列,但这些是唯一相关的列)。我的第二个df是“tableB”并且有一个时间戳。以下是一些示例数据:

tableA <- data.frame("start" = 1:5, "stop"= 2:6, "numb" = 11:15)

tableB <- data.frame("timeStamp" = c(1.7, 2.1, 2.4, 2.8, 4.5), "numb" = 0)

这将导致帧看起来像这样:

tableA                     tableB
start  stop  numb          timeStamp  numb
1      2     11            1.7        0
2      3     12            2.1        0
3      4     13            2.4        0  
4      5     14            2.8        0 
5      6     15            4.5        0

我正在尝试将 tableB 中的所有时间戳标记为 tableA 中的相应数字,当它位于开始时间和停止时间之间时。例如,对于表 B (1.7) 中的第一行,它将获得数字 11(因为它介于 1 和 2 之间)。所以对于这些数据,我希望 tableB 看起来像这样:

tableB 
timeStamp  numb
1.7        11
2.1        12
2.4        12
2.8        12
4.5        14

为此,我编写了以下嵌套循环语句:

for(n in 1:length(tableB$timeStamp)) {
  for(i in 1:length(tableA$numb)) {
    if(tableB$timeStamp[n] > tableA$start[i] &
       tableB$timeStamp[n] < tableA$stop[i]) {
         tableB$numb[n] <- tableA$numb[i]
         sprintf("n = %i", n)
         sprintf("i = %i", i)}
   }
  }

但是,tableB$numb 中的所有值都刚刚更改为 5,并且没有任何内容打印到控制台。我不确定我在这里搞砸了什么,因为它似乎甚至从未进入 if 语句,但 tableB$numb 的更新不正确。任何提示或帮助将不胜感激!

标签: rfor-loopif-statementnestedrstudio

解决方案


一个更简单的选项,如果您愿意使用fuzzyjoin包,可能是这样的:

tableA <- data.frame("start" = 1:5, "stop"= 2:6, "numb" = 11:15)
tableB <- data.frame("timeStamp" = c(1.7, 2.1, 2.4, 2.8, 4.5))

> fuzzy_left_join(tableB,tableA,
                by = c("timeStamp" = "start","timeStamp" = "stop"),
                match_fun = list(`>=`,`<=`))

  timeStamp start stop numb
1       1.7     1    2   11
2       2.1     2    3   12
3       2.4     2    3   12
4       2.8     2    3   12
5       4.5     4    5   14

推荐阅读