【问题标题】:all vs. all comparisons between two dataframes using apply使用 apply 在两个数据帧之间进行全部与全部比较
【发布时间】:2021-04-24 10:01:03
【问题描述】:

我正在使用 R,并且我有三个数据帧,其中包含两个相同的列(ID 和时间戳),但行数不同。

ID       timeStamp
a   2018-04-17 10:47:45
a   2018-04-17 10:47:48
a   2018-04-17 10:47:48
a   2018-04-17 10:47:48
a   2018-04-17 10:49:23
a   2018-04-17 10:50:02
a   2018-04-17 10:51:34
a   2018-04-17 10:51:36
a   2018-04-17 10:51:38


ID       timeStamp
b   2018-04-17 10:32:17
b   2018-04-17 10:46:18
b   2018-04-17 10:47:18
b   2018-04-17 10:49:20
b   2018-04-17 10:52:22
b   2018-04-17 10:55:25
b   2018-04-17 10:57:29

ID       timeStamp
c   2018-04-17 10:32:17
c   2018-04-17 10:46:18
c   2018-04-17 10:47:18
c   2018-04-17 10:49:20
c   2018-04-17 10:52:22
c   2018-04-17 10:55:25

我想比较三个数据帧中的所有时间戳值,并根据数据帧 A、B 和 C 中的观测值在特定时间范围内的次数来计算点。例如,如果两个 obs 在 5 分钟范围内,我想分配 10 分。如果值完全相同,它将获得 5 分。否则不加分。我想得到两个数据框之间的总分

我尝试使用 for 循环制作模型,但是当我比较大量行时需要很长时间。

m= 0
n= 0
for (i in 1:nrow(A)){
  for (j in 1:nrow(B)){if (difftime(A[i,"tStamp"],B[j,"tStamp"],units = "secs") < 300 & A(Role1[i,"tStamp"],B[j,"tStamp"],units = "secs") >0 ) {m=m+10}
else if ( difftime(A[i,"tStamp"],B[j,"tStamp"],units = "secs") == 0){m=m+5}
else if (difftime(B[j,"tStamp"],A[i,"tStamp"],units = "secs") < 300 & difftime(B[j,"tStamp"],A[i,"tStamp"],units = "secs") >0) {n=n+10}
else if ( difftime(B[j,"tStamp"],A[i,"tStamp"],units = "secs") == 0){n=n+5}}

是否有使用 apply 函数的好方法?我相信它会比 for 循环更有效和更快。预期的输出将像

ID1     ID2               m              n
A        B     
A        C      
B        C   

m 和 n 将是循环后两个数据帧关系的总加点。 任何帮助将不胜感激。

【问题讨论】:

  • if 不是矢量化运算符,因此您的 if (difftime...) 逻辑不正确。此外,即使您要使用ifelse 对比较进行矢量化,当m != n 时,您也无法将m 元素的矢量与n 元素的矢量进行比较。
  • Inkyu,我认为,如果您根据此示例数据提供预期的输出,将会有所帮助。
  • @r2evans 感谢您的快速和友好的 cmets。我添加了更详细的解释和我的预期输出。再次感谢您的帮助!

标签: r loops comparison apply


【解决方案1】:

我不确定您要寻找什么样的最终输出,但首先您可以使用 outerdifftime

mat <- outer(df1$timeStamp, df2$timeStamp, difftime, units = 'mins')
mat

#Time differences in mins
#      [,1] [,2] [,3]  [,4]   [,5]  [,6]  [,7]
# [1,] 15.5 1.45 0.45 -1.58 -4.617 -7.67 -9.73
# [2,] 15.5 1.50 0.50 -1.53 -4.567 -7.62 -9.68
# [3,] 15.5 1.50 0.50 -1.53 -4.567 -7.62 -9.68
# [4,] 15.5 1.50 0.50 -1.53 -4.567 -7.62 -9.68
# [5,] 17.1 3.08 2.08  0.05 -2.983 -6.03 -8.10
# [6,] 17.8 3.73 2.73  0.70 -2.333 -5.38 -7.45
# [7,] 19.3 5.27 4.27  2.23 -0.800 -3.85 -5.92
# [8,] 19.3 5.30 4.30  2.27 -0.767 -3.82 -5.88
# [9,] 19.4 5.33 4.33  2.30 -0.733 -3.78 -5.85

从这里您可能想要获取可用值的绝对值并将小于 5 的值变为 10 并相应地执行计算。

【讨论】:

  • 谢谢!我感谢您为帮助我解决此问题所付出的所有努力!这与我的预期有点不同,但我相信我可以利用它来得到我想要的!
  • Inkyu,既然你是新人......当你准备好并考虑解决这个问题时,请回到这里并accept这个答案。一般来说,如果有多个答案,您只能接受一个,但可以随意投票(包括您接受的那个)。这样做不仅为回答者提供了一些积分,而且还为有类似问题的读者提供了一些关闭。同样,不要着急(有时可以提供其他好的答案),但请记得回来。谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-01-02
  • 1970-01-01
  • 2020-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-26
相关资源
最近更新 更多