Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/80.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.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 在较大的二维表格中查找二维表格_R_Performance_Data.table - Fatal编程技术网

R 在较大的二维表格中查找二维表格

R 在较大的二维表格中查找二维表格,r,performance,data.table,R,Performance,Data.table,我的问题如下: 我正在寻找在较大的表中查找2D表的列和行索引的最快方法。小表的大小为nxm,在j>n和k>m的较大的jxk表中可以出现多次。我一直在尝试使用“data.table”包实现这一点,但失败了。我的问题与下面的问题非常相似: 但我希望在R中快速完成这项工作。在使用for循环实现蛮力方法之前,我想听听您的看法。请注意,表中可能有数字和字符串 如果你需要一个例子。你可以考虑我需要搜索下面的数据帧: data.frame(A=c(1.7,1.5,1.7),B=c(0.3,0.3,0.2),C

我的问题如下:

我正在寻找在较大的表中查找2D表的列和行索引的最快方法。小表的大小为nxm,在j>n和k>m的较大的jxk表中可以出现多次。我一直在尝试使用“data.table”包实现这一点,但失败了。我的问题与下面的问题非常相似:

但我希望在R中快速完成这项工作。在使用for循环实现蛮力方法之前,我想听听您的看法。请注意,表中可能有数字和字符串

如果你需要一个例子。你可以考虑我需要搜索下面的数据帧:

data.frame(A=c(1.7,1.5,1.7),B=c(0.3,0.3,0.2),C=c("setosa","setosa","setosa"))
您必须在“iris”数据框中搜索。输出答案是: 第19行和第3列。

基于:

库(dplyr)
#检查相等时出现的因素问题,请改为使用字符串
df1%
dplyr::mutate_if(is.factor,as.character)
df%
dplyr::mutate_if(is.factor,as.character)
#查找df1左上角的所有匹配项
点击次数基于:

库(dplyr)
#检查相等时出现的因素问题,请改为使用字符串
df1%
dplyr::mutate_if(is.factor,as.character)
df%
dplyr::mutate_if(is.factor,as.character)
#查找df1左上角的所有匹配项

点击
数据。表
对于关系表来说很快,但是基本的
矩阵
非常快。我的建议是将表存储为矩阵,并使用更简单的子集来比较子矩阵

从一些示例数据开始:
bigmat
是我们将在其中查找匹配项的大矩阵,
smallmat\u in
bigmat
的子矩阵,
smallmat\u out
是不在
bigmat
内的矩阵

bigmat <- matrix(c(1:50, 1:50), nrow = 10)
smallmat_in <- bigmat[6:8, 2:3]
smallmat_out <- smallmat_in
smallmat_out[6] <- 0

bigmat
#       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#  [1,]    1   11   21   31   41    1   11   21   31    41
#  [2,]    2   12   22   32   42    2   12   22   32    42
#  [3,]    3   13   23   33   43    3   13   23   33    43
#  [4,]    4   14   24   34   44    4   14   24   34    44
#  [5,]    5   15   25   35   45    5   15   25   35    45
#  [6,]    6   16   26   36   46    6   16   26   36    46
#  [7,]    7   17   27   37   47    7   17   27   37    47
#  [8,]    8   18   28   38   48    8   18   28   38    48
#  [9,]    9   19   29   39   49    9   19   29   39    49
# [10,]   10   20   30   40   50   10   20   30   40    50

smallmat_in
#      [,1] [,2]
# [1,]   16   26
# [2,]   17   27
# [3,]   18   28

smallmat_out
#      [,1] [,2]
# [1,]   16   26
# [2,]   17   27
# [3,]   18    0
smallmat_in
smallmat_out
仅在最后一个元素上不同,因此它们的第一个元素具有相同的匹配项。接下来,我们将定义一个函数,它接受一个小矩阵(
small
)、一个大矩阵(
big
)和一个行-列对(
big\u first\u index
)。如果行-列对是与
small
匹配的
big
子矩阵的左上角,则返回
TRUE
。否则,
FALSE

is_matrix_match <- function(small, big, big_first_index) {
  row_indices <- seq(big_first_index[1], by = 1, length.out = nrow(small))
  col_indices <- seq(big_first_index[2], by = 1, length.out = ncol(small))
  all(small == big[row_indices, col_indices])
}

is_matrix_match(smallmat_in, bigmat, c(6, 2))
# [1] TRUE

is_matrix_match(smallmat_out, bigmat, c(6, 2))
# [1] FALSE
因为这是一个概念证明,所以它没有任何检查(比如确保
big
实际上大于
small
)。在生产环境中拥有这些将是很好的

我不知道您使用的矩阵有多大,但以下是我对更大矩阵的一些速度测量:

hugemat <- matrix(rep_len(1:7, 1e7), nrow = 10)
format(object.size(hugemat), "MB")
# [1] "38.1 Mb"

huge_submat <- hugemat[2:9, 200:300]
huge_not_submat <- huge_submat
huge_not_submat[] <- 1

system.time(in_matrix(huge_submat, hugemat))
#  user  system elapsed
# 10.51    0.00   10.53

system.time(in_matrix(huge_not_submat, hugemat))
#  user  system elapsed
# 10.62    0.00   10.69

hugemat
data.table
对于关系表来说非常快,但是基本的
矩阵
非常快。我的建议是将表存储为矩阵,并使用更简单的子集来比较子矩阵

从一些示例数据开始:
bigmat
是我们将在其中查找匹配项的大矩阵,
smallmat\u in
bigmat
的子矩阵,
smallmat\u out
是不在
bigmat
内的矩阵

bigmat <- matrix(c(1:50, 1:50), nrow = 10)
smallmat_in <- bigmat[6:8, 2:3]
smallmat_out <- smallmat_in
smallmat_out[6] <- 0

bigmat
#       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
#  [1,]    1   11   21   31   41    1   11   21   31    41
#  [2,]    2   12   22   32   42    2   12   22   32    42
#  [3,]    3   13   23   33   43    3   13   23   33    43
#  [4,]    4   14   24   34   44    4   14   24   34    44
#  [5,]    5   15   25   35   45    5   15   25   35    45
#  [6,]    6   16   26   36   46    6   16   26   36    46
#  [7,]    7   17   27   37   47    7   17   27   37    47
#  [8,]    8   18   28   38   48    8   18   28   38    48
#  [9,]    9   19   29   39   49    9   19   29   39    49
# [10,]   10   20   30   40   50   10   20   30   40    50

smallmat_in
#      [,1] [,2]
# [1,]   16   26
# [2,]   17   27
# [3,]   18   28

smallmat_out
#      [,1] [,2]
# [1,]   16   26
# [2,]   17   27
# [3,]   18    0
smallmat_in
smallmat_out
仅在最后一个元素上不同,因此它们的第一个元素具有相同的匹配项。接下来,我们将定义一个函数,它接受一个小矩阵(
small
)、一个大矩阵(
big
)和一个行-列对(
big\u first\u index
)。如果行-列对是与
small
匹配的
big
子矩阵的左上角,则返回
TRUE
。否则,
FALSE

is_matrix_match <- function(small, big, big_first_index) {
  row_indices <- seq(big_first_index[1], by = 1, length.out = nrow(small))
  col_indices <- seq(big_first_index[2], by = 1, length.out = ncol(small))
  all(small == big[row_indices, col_indices])
}

is_matrix_match(smallmat_in, bigmat, c(6, 2))
# [1] TRUE

is_matrix_match(smallmat_out, bigmat, c(6, 2))
# [1] FALSE
因为这是一个概念证明,所以它没有任何检查(比如确保
big
实际上大于
small
)。在生产环境中拥有这些将是很好的

我不知道您使用的矩阵有多大,但以下是我对更大矩阵的一些速度测量:

hugemat <- matrix(rep_len(1:7, 1e7), nrow = 10)
format(object.size(hugemat), "MB")
# [1] "38.1 Mb"

huge_submat <- hugemat[2:9, 200:300]
huge_not_submat <- huge_submat
huge_not_submat[] <- 1

system.time(in_matrix(huge_submat, hugemat))
#  user  system elapsed
# 10.51    0.00   10.53

system.time(in_matrix(huge_not_submat, hugemat))
#  user  system elapsed
# 10.62    0.00   10.69

hugemat软件包
kit
中的函数
fpos
返回一个较大矩阵中一个小矩阵的位置。它也适用于向量。将data.frame转换为矩阵,然后使用
fpos
。请注意,该函数是用C实现的,因此速度应该很快。

package
kit
中的函数
fpos
会返回较大矩阵中的小矩阵位置。它也适用于向量。将data.frame转换为矩阵,然后使用
fpos
。请注意,该函数是用C实现的,因此速度应该很快。

请看一看,如果它是您要查找的,我会将其标记为dup,但您不应删除它,因为它以不同的方式被询问,可能会帮助其他人找到它。@hrbrmstr,谢谢您的回复。问题在某种程度上相似,但不确定是否相同。在您提供的链接中,有2个答案不起作用或不完整,Rcpp答案返回错误。我试图调试它,但没有成功。请看一看,如果它是您想要的,我会将它标记为dup,但您不能删除它,因为它以不同的方式被询问,可能会帮助其他人找到它。@hrbrmstr,谢谢您的回复。问题在某种程度上相似,但不确定是否相同。在您提供的链接中,有2个答案不起作用或不完整,Rcpp答案返回错误。我试着调试它,但没有成功。谢谢你的回复。我发现在大桌子上比较慢,不过我会接受你的答案。我会在你提供的基础上尝试更快的实现。谢谢你的回复。我发现在大桌子上比较慢,不过我会接受你的答案。我将尝试根据您提供的内容更快地实现某些功能。使用矩阵可能是个好主意,但您如何处理OP的要求:请注意,在表中,您可能有数字和字符串。@Uwe我的解决方案不依赖数字比较,因此它也适用于字符矩阵。任何数字数据都可以转换为字符。@Nath