Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 从较大的“查找”样式data.table中查找最接近的2列值_R_Data.table_Lookup_Closest - Fatal编程技术网

R 从较大的“查找”样式data.table中查找最接近的2列值

R 从较大的“查找”样式data.table中查找最接近的2列值,r,data.table,lookup,closest,R,Data.table,Lookup,Closest,我有一个data.table dt_1,其中包含观察到的两列和观察到的两列的测量值。我需要使用这些列中的值,并在第二个查找样式的data.table dt_2中查找与这两列最近的值。table dt_2分别引用建模的列和建模的列。最终目标是,使用dt_2中最接近匹配的行,选择dt_2变量_1、变量_2和变量_3中的3个附加建模列值,并将它们添加到dt_1中 我希望使用data.table的roll函数作为我的实际数据;30列和35000行dt_2;17列和15000行,但我不确定如何用2列同时完

我有一个data.table dt_1,其中包含观察到的两列和观察到的两列的测量值。我需要使用这些列中的值,并在第二个查找样式的data.table dt_2中查找与这两列最近的值。table dt_2分别引用建模的列和建模的列。最终目标是,使用dt_2中最接近匹配的行,选择dt_2变量_1、变量_2和变量_3中的3个附加建模列值,并将它们添加到dt_1中

我希望使用data.table的roll函数作为我的实际数据;30列和35000行dt_2;17列和15000行,但我不确定如何用2列同时完成这一任务

以下是一些示例数据:

dt_1 <- structure(list(Observed_A = c(-9.7, -10.8, -9.7, -9.2, -9.5, 
-10.1, -8.3, -7.6), Observed_B = c(-3.1, -5.2, -4.5, -4.1, -3, 
-2.7, -2.6, -2.6)), class = "data.frame", row.names = c(NA, -8L))
注意:我通常不会发布这么长的dt_2示例,但我认为问题的本质证明了这一点。

我不擅长data.table,但这里有一个小方法可以帮助您-

dt_1 %>% 
  tibble::rownames_to_column("id") %>% 
  mutate(cj = 1) %>% 
  inner_join(dt_2 %>% mutate(cj = 1), by = "cj") %>%
  select(-cj) %>% 
  mutate(
    closeness = abs(Observed_A - Modeled_A) + abs(Observed_B - Modeled_B),
    # closeness = 0 means perfect match
  ) %>% 
  arrange(id, closeness) %>% 
  group_by(id) %>% 
  slice(1) %>% 
  ungroup()

# A tibble: 8 x 9
  id    Observed_A Observed_B Modeled_A Modeled_B Variable_1 Variable_2 Variable_3 closeness
  <chr>      <dbl>      <dbl>     <dbl>     <dbl>      <int>      <int>      <int>     <dbl>
1 1         - 9.70      -3.10    - 9.80     -2.80          4        448        251     0.400
2 2         -10.8       -5.20    -11.4      -5.90         80        865         63     1.30 
3 3         - 9.70      -4.50    - 9.80     -4.30         37        857        281     0.300
4 4         - 9.20      -4.10    - 9.80     -4.30         37        857        281     0.800
5 5         - 9.50      -3.00    - 9.80     -2.80          4        448        251     0.500
6 6         -10.1       -2.70    - 9.80     -2.80          4        448        251     0.400
7 7         - 8.30      -2.60    - 8.20     -2.80         86        885        246     0.300
8 8         - 7.60      -2.60    - 8.20     -2.80         86        885        246     0.800
我不擅长data.table,但这里有一个简单的方法可以帮助您-

dt_1 %>% 
  tibble::rownames_to_column("id") %>% 
  mutate(cj = 1) %>% 
  inner_join(dt_2 %>% mutate(cj = 1), by = "cj") %>%
  select(-cj) %>% 
  mutate(
    closeness = abs(Observed_A - Modeled_A) + abs(Observed_B - Modeled_B),
    # closeness = 0 means perfect match
  ) %>% 
  arrange(id, closeness) %>% 
  group_by(id) %>% 
  slice(1) %>% 
  ungroup()

# A tibble: 8 x 9
  id    Observed_A Observed_B Modeled_A Modeled_B Variable_1 Variable_2 Variable_3 closeness
  <chr>      <dbl>      <dbl>     <dbl>     <dbl>      <int>      <int>      <int>     <dbl>
1 1         - 9.70      -3.10    - 9.80     -2.80          4        448        251     0.400
2 2         -10.8       -5.20    -11.4      -5.90         80        865         63     1.30 
3 3         - 9.70      -4.50    - 9.80     -4.30         37        857        281     0.300
4 4         - 9.20      -4.10    - 9.80     -4.30         37        857        281     0.800
5 5         - 9.50      -3.00    - 9.80     -2.80          4        448        251     0.500
6 6         -10.1       -2.70    - 9.80     -2.80          4        448        251     0.400
7 7         - 8.30      -2.60    - 8.20     -2.80         86        885        246     0.300
8 8         - 7.60      -2.60    - 8.20     -2.80         86        885        246     0.800

使用与Shree相同的距离度量,但在data.table中,不要认为它会更快:

library(data.table)
setDT(dt_1)
setDT(dt_2)
dt_1[, c(.SD, dt_2[which.min(abs(Observed_A-Modeled_A) + abs(Observed_B-Modeled_B))]), 
    by=dt_1[, seq_len(.N)]]
输出:

   dt_1 Observed_A Observed_B Modeled_A Modeled_B Variable_1 Variable_2 Variable_3
1:    1       -9.7       -3.1      -9.8      -2.8          4        448        251
2:    2      -10.8       -5.2     -11.4      -5.9         80        865         63
3:    3       -9.7       -4.5      -9.8      -4.3         37        857        281
4:    4       -9.2       -4.1      -9.8      -4.3         37        857        281
5:    5       -9.5       -3.0      -9.8      -2.8          4        448        251
6:    6      -10.1       -2.7      -9.8      -2.8          4        448        251
7:    7       -8.3       -2.6      -8.2      -2.8         86        885        246
8:    8       -7.6       -2.6      -8.2      -2.8         86        885        246
编辑: 速度差异可能是由于列数过多造成的。使用参照更新的另一种可能性:

library(data.table)
setDT(dt_1)
setDT(dt_2)
dt_1[, names(dt_2) := dt_2[which.min(abs(Observed_A-Modeled_A) + abs(Observed_B-Modeled_B))]), 
    by=dt_1[, seq_len(.N)]]

或者,如果dt_1和dt_2都是矩阵,则使用基数R可能更快。

使用与Shree相同的距离度量,但在data.table中,不认为它会更快:

library(data.table)
setDT(dt_1)
setDT(dt_2)
dt_1[, c(.SD, dt_2[which.min(abs(Observed_A-Modeled_A) + abs(Observed_B-Modeled_B))]), 
    by=dt_1[, seq_len(.N)]]
输出:

   dt_1 Observed_A Observed_B Modeled_A Modeled_B Variable_1 Variable_2 Variable_3
1:    1       -9.7       -3.1      -9.8      -2.8          4        448        251
2:    2      -10.8       -5.2     -11.4      -5.9         80        865         63
3:    3       -9.7       -4.5      -9.8      -4.3         37        857        281
4:    4       -9.2       -4.1      -9.8      -4.3         37        857        281
5:    5       -9.5       -3.0      -9.8      -2.8          4        448        251
6:    6      -10.1       -2.7      -9.8      -2.8          4        448        251
7:    7       -8.3       -2.6      -8.2      -2.8         86        885        246
8:    8       -7.6       -2.6      -8.2      -2.8         86        885        246
编辑: 速度差异可能是由于列数过多造成的。使用参照更新的另一种可能性:

library(data.table)
setDT(dt_1)
setDT(dt_2)
dt_1[, names(dt_2) := dt_2[which.min(abs(Observed_A-Modeled_A) + abs(Observed_B-Modeled_B))]), 
    by=dt_1[, seq_len(.N)]]
或者,如果dt_1和dt_2都是矩阵,则使用基数R可能更快。

比较答案的执行时间

实际数据的执行时间

我包含这一点是为了显示较大数据表的性能差异,其中dtu 1由约35000行30列组成,dtu 2由约15000行17列组成

比较答案的执行时间

实际数据的执行时间

我包含这一点是为了显示较大数据表的性能差异,其中dtu 1由约35000行30列组成,dtu 2由约15000行17列组成


你的答案很有用。我不接受它的唯一原因是因为我需要使用data.table,因为我的实际dt_1包含超过35000个观察值和30个变量,而我的实际dt_2包含超过15000个观察值和17个变量。我在上面尝试了你的代码,但由于dplyr占用内存的特性,内存耗尽了16 gb。我认为交叉连接可能是内存方面的主要原因。它创建了35000*15000 525MM行和47列,这当然很大。我来看看是否有办法避免交叉连接。这样效果更好!好奇的是,如果我观察到第三个测量列,第三个建模列,我会在代码中添加sliceapplydt_1[,-1],1,functionx{absx[1]-dt_2$modeled_a+absx[2]-dt_2$modeled_B+absx[3]-dt_2$modeled_C%>%which.min}太棒了。再次感谢。你的回答很有效。我不接受它的唯一原因是因为我需要使用data.table,因为我的实际dt_1包含超过35000个观察值和30个变量,而我的实际dt_2包含超过15000个观察值和17个变量。我在上面尝试了你的代码,但由于dplyr占用内存的特性,内存耗尽了16 gb。我认为交叉连接可能是内存方面的主要原因。它创建了35000*15000 525MM行和47列,这当然很大。我来看看是否有办法避免交叉连接。这样效果更好!好奇的是,如果我观察到第三个测量列,第三个建模列,我会在代码中添加sliceapplydt_1[,-1],1,functionx{absx[1]-dt_2$modeled_a+absx[2]-dt_2$modeled_B+absx[3]-dt_2$modeled_C%>%which.min}太棒了。再次感谢。感谢@chinsoon12和@Shree,我做了一个快速的性能检查,看看哪种方法更有效。我必须发布一个答案,因为我的OP超过了字符限制。dplyr在执行时间上胜过data.table!您好@chinsoon12,我已经用您新的data.table引用版本data.table.reference更新了我的回复。看起来dplyr更快。另外,您的代码中还有一个额外的。这对我有效:dt_1[,名称dt_2:=dt_2[which.minabsObserved_A-Modeled_A+absObserved_B-Modeled_B],by=dt_1[,seq_len.N]]谢谢@chinsoon12和@Shree,我做了一个快速的性能检查,看看哪种方法更有效,因为我的OP超过了字符限制,我不得不发布一个答案。dplyr在执行时间上胜过data.table!您好@chinsoon12,我已经用您新的data.table引用版本data.table.reference更新了我的回复。看起来dplyr更快。另外,您的代码中还有一个额外的。这对我有效:dt_1[,名称dt_2:=dt_2[w
我有点惊讶。也许在这两个软件包中都有经验的人可以提供一些信息。我认为这是因为专栏的数量。我将尝试使用另一种索引方法,而不是.SD。之后,我有点惊讶。也许在这两个软件包中都有经验的人可以提供一些信息。我认为这是因为专栏的数量。稍后我将尝试使用另一种索引方法,而不是.SD