在 R 中查找矩阵的相邻元素

2024-01-01

编辑:非常感谢以下用户的巨大贡献以及 Gregor 的基准测试。

假设我有一个充满整数值的矩阵,如下所示......

    mat <- matrix(1:100, 10, 10)

我可以像这样创建每个元素的 x、y 坐标列表......

    addresses <- expand.grid(x = 1:10, y = 1:10)

现在,对于每个坐标(即 mat 中的每个元素),我想找到相邻元素(包括对角线,这应该有 8 个邻居)。

我确信有一个简单的方法,有人可以帮忙吗?

到目前为止我尝试过的是循环遍历并为每个元素记录相邻元素,如下所示;

    neighbours <- list()
    for(i in 1:dim(addresses)[1]){
      x <- addresses$x[i]
      y <- addresses$y[i]
      neighbours[[i]] <- c(mat[y-1, x  ],
                           mat[y-1, x+1],
                           mat[y  , x+1],
                           mat[y+1, x+1],
                           mat[y+1, x  ],
                           mat[y+1, x-1],
                           mat[y  , x-1],
                           mat[y-1, x-1])
    }

当它触及矩阵的边缘时,特别是当索引大于矩阵的边缘时,这会遇到问题。


这是一个很好的例子。我做了 4x4 所以我们可以很容易地看到它,但它都是可以调整的n。它也是完全矢量化的,因此应该具有良好的速度。

n = 4
mat = matrix(1:n^2, nrow = n)
mat.pad = rbind(NA, cbind(NA, mat, NA), NA)

对于填充矩阵,邻居只是 n × n 子矩阵,四处移动。使用罗盘方向作为标签:

ind = 2:(n + 1) # row/column indices of the "middle"
neigh = rbind(N  = as.vector(mat.pad[ind - 1, ind    ]),
              NE = as.vector(mat.pad[ind - 1, ind + 1]),
              E  = as.vector(mat.pad[ind    , ind + 1]),
              SE = as.vector(mat.pad[ind + 1, ind + 1]),
              S  = as.vector(mat.pad[ind + 1, ind    ]),
              SW = as.vector(mat.pad[ind + 1, ind - 1]),
              W  = as.vector(mat.pad[ind    , ind - 1]),
              NW = as.vector(mat.pad[ind - 1, ind - 1]))

mat
#      [,1] [,2] [,3] [,4]
# [1,]    1    5    9   13
# [2,]    2    6   10   14
# [3,]    3    7   11   15
# [4,]    4    8   12   16

  neigh[, 1:6]
#    [,1] [,2] [,3] [,4] [,5] [,6]
# N    NA    1    2    3   NA    5
# NE   NA    5    6    7   NA    9
# E     5    6    7    8    9   10
# SE    6    7    8   NA   10   11
# S     2    3    4   NA    6    7
# SW   NA   NA   NA   NA    2    3
# W    NA   NA   NA   NA    1    2
# NW   NA   NA   NA   NA   NA    1

所以你可以看到第一个元素mat[1,1],从北开始,顺时针方向,邻居是第一列neigh。下一个元素是mat[2,1],依此类推mat。 (您还可以与 @mrip 的答案进行比较,看到我们的列具有相同的元素,只是顺序不同。)

标杆管理

小矩阵

mat = matrix(1:16, nrow = 4)
mbm(gregor(mat), mrip(mat), marat(mat), u20650(mat), times = 100)
# Unit: microseconds
#         expr     min       lq      mean   median       uq      max neval  cld
#  gregor(mat)  25.054  30.0345  34.04585  31.9960  34.7130   61.879   100 a   
#    mrip(mat) 420.167 443.7120 482.44136 466.1995 483.4045 1820.121   100   c 
#   marat(mat) 746.462 784.0410 812.10347 808.1880 832.4870  911.570   100    d
#  u20650(mat) 186.843 206.4620 220.07242 217.3285 230.7605  269.850   100  b  

在更大的矩阵上,我不得不取出 user20650 的函数,因为它试图分配 232.8 Gb 向量,并且在等待大约 10 分钟后我还取出了 Marat 的答案。

mat = matrix(1:500^2, nrow = 500)

mbm(gregor(mat), mrip(mat), times = 100)
# Unit: milliseconds
#         expr       min        lq      mean    median        uq      max neval cld
#  gregor(mat) 19.583951 21.127883 30.674130 21.656866 22.433661 127.2279   100   b
#    mrip(mat)  2.213725  2.368421  8.957648  2.758102  2.958677 104.9983   100  a 

所以看起来在任何时间很重要的情况下,@mr​​ip 的解决方案都是迄今为止最快的。

使用的函数:

gregor = function(mat) {
    n = nrow(mat)
    mat.pad = rbind(NA, cbind(NA, mat, NA), NA)
    ind = 2:(n + 1) # row/column indices of the "middle"
    neigh = rbind(N  = as.vector(mat.pad[ind - 1, ind    ]),
                  NE = as.vector(mat.pad[ind - 1, ind + 1]),
                  E  = as.vector(mat.pad[ind    , ind + 1]),
                  SE = as.vector(mat.pad[ind + 1, ind + 1]),
                  S  = as.vector(mat.pad[ind + 1, ind    ]),
                  SW = as.vector(mat.pad[ind + 1, ind - 1]),
                  W  = as.vector(mat.pad[ind    , ind - 1]),
                  NW = as.vector(mat.pad[ind - 1, ind - 1]))
    return(neigh)
}

mrip = function(mat) {
    m2<-cbind(NA,rbind(NA,mat,NA),NA)
    addresses <- expand.grid(x = 1:4, y = 1:4)
    ret <- c()
    for(i in 1:-1)
        for(j in 1:-1)
            if(i!=0 || j !=0)
                ret <- rbind(ret,m2[addresses$x+i+1+nrow(m2)*(addresses$y+j)]) 
    return(ret)
}

get.neighbors <- function(rw, z, mat) {
    # Convert to absolute addresses 
    z2 <- t(z + unlist(rw))
    # Choose those with indices within mat 
    b.good <- rowSums(z2 > 0)==2  &  z2[,1] <= nrow(mat)  &  z2[,2] <= ncol(mat)
    mat[z2[b.good,]]
}

marat = function(mat) {
    n.row = n.col = nrow(mat)
    addresses <- expand.grid(x = 1:n.row, y = 1:n.col)
    # Relative addresses
    z <- rbind(c(-1,0,1,-1,1,-1,0,1), c(-1,-1,-1,0,0,1,1,1))
    apply(addresses, 1,
          get.neighbors, z = z, mat = mat) # Returns a list with neighbors
}

u20650 = function(mat) {
    w <-  which(mat==mat, arr.ind=TRUE)
    d <- as.matrix(dist(w, "maximum", diag=TRUE, upper=TRUE))
    # extract neighbouring values for each element
    # extract where max distance is one
    a <- apply(d, 1, function(i) mat[i == 1] )
    names(a)  <- mat
    return(a)
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 R 中查找矩阵的相邻元素 的相关文章

  • 从 leafletProxy() 返回渲染的传单地图

    是否可以在渲染后在 Shiny 中检索传单地图 下面是一个代码示例 展示了如何生成地图leaflet 与返回的不同leafletProxy 即使它们在渲染时看起来完全相同 是否有一个功能可能不同于leafletProxy 获取实际的 htm
  • 如何在有条件的情况下获得R中多列的中位数(根据另一列)

    我是 R 初学者 我想知道如何完成以下任务 我想用数据集所有列的中位数替换数据集的缺失值 但是 对于每一列 我想要某个类别的中位数 取决于另一列 我的数据集如下 structure list Country structure 1 5 La
  • dplyr::group_by_ 带有多个变量名的字符串输入

    我正在编写一个函数 要求用户在函数调用中定义一个或多个分组变量 然后使用 dplyr 对数据进行分组 如果只有一个分组变量 它会按预期工作 但我还没有弄清楚如何使用多个分组变量来做到这一点 Example x lt c cyl y lt c
  • 为特定 ID 重新编码列中的观察结果

    我有一个数据集 称为 调查 其中有行是个人 ID 列中有许多问题 我需要将 1 列中的值重新编码为 NA 并将观察结果移至另一列 例如 ID Fruit Vegetable aaa NA grape bbb NA tomato ccc ap
  • 是否可以创建根据输入对象名称自行命名的列表?

    能够创建 R 列表对象而无需指定每个元素的名称对我来说非常有帮助 例如 a1 lt 1 a2 lt 20 a3 lt 1 20 b lt list a1 a2 a3 inherit name TRUE gt b a1 1 1 a2 1 20
  • R ggplot:加权 CDF

    我想使用绘制加权 CDFggplot 一些旧的非 SO 讨论 例如this https stat ethz ch pipermail r help 2012 October 337288 html从 2012 年起 建议这是不可能的 但我想
  • 消除垂直线ggplot

    这个问题以前曾被问过 但答案并不总是明确或很复杂 我希望 ggplot2 的新版本能够带来更简单的解决方案 如何仅消除 ggplot 的垂直线而不消除轴刻度线或标签 这对于条形图来说确实很好 因为它可以消除图形中一些不必要的干扰 这里有一些
  • R - 加速近似日期匹配。 idata.frame?

    我正在努力有效地执行两个数据帧之间的 关闭 日期匹配 这个问题探索了一个解决方案 使用idata frame来自plyr包 但我也对其他建议的解决方案感到非常满意 这是两个数据框的非常简单的版本 sampleticker lt data f
  • 将 R 中的列中的单引号替换为双引号

    我在 R 中的数据框有一个 A 列 其中有带单引号的字符串数据 Column A Hello World Hi World Good morning world 我想做的是将单引号替换为双引号并实现如下所示的输出 Column A Hell
  • R闪亮:在渲染表格时显示“正在加载...”消息

    在 Rstudio Shiny 中 我得到了一些renderDataTable通过 RMySQL 从数据库获取信息的调用 有些查询可能需要几秒钟才能完成 我想添加一条 正在加载 消息 其中表格将在等待时最终呈现 这个问题与这个问题类似 R闪
  • r 闪亮下载过滤数据表(DT)

    我正在尝试做一个shiny应用程序下载过滤后的Datatable 过滤与search 通过删除行进行过滤delete button 下载部分按预期工作 问题 当我第一次使用数据表中的搜索区域进行过滤时 如果我使用按钮删除一行 它会重置第一个
  • 在C中分配矩阵

    我想分配一个矩阵 这是唯一的选择吗 int mat int malloc rows sizeof int for int index 0 index
  • ggplot:如何检索轴标签的值?

    如何提取下面的 ggplot 中用于标记 y 轴和 x 轴的数字 分别为20 30 40 and 10 15 20 25 30 35 Plot From r 统计公司 http r statistics co Top50 Ggplot2 V
  • 如何计算由离散数据定义的表面下的体积?

    我需要确定由离散数据点表示的一系列表面下方的体积 在我的数据中 每个样本都作为数据帧列表中的单独数据帧存储 这是一些 小 示例数据 df1 lt data frame x c 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6 y
  • R: pi[[j]] 中的错误:下标越界——数据帧列表上的 rbind

    我正在尝试重新绑定一个大的数据帧列表 outputDfList 它是通过将一个复杂的函数应用于一个大表而生成的 您可以通过以下方式重新创建outputDfList df1 data frame randomseq chr15q22 1 tr
  • ggplot2错误:美学必须是长度一,或者与数据长度相同问题:颜色、字母

    我收到此错误 错误 美学必须是长度一 或者与数据长度相同问题 颜色 字母 当我将 ggplot 与数据框一起使用时Z如图所示 Z lt data frame Name c A G C T T T AG AG GC GC CT CT AT A
  • r - 如何在 normalizePath 中指定路径,或解决与其关联的此错误?

    我正在学习 R 并将其安装在我的办公室计算机上 我没有计算机的管理员权限 因为我什至必须致电IT人员进行安装 然后我安装一个包 一开始输入时不起作用 例如 install packages thepackage 错误信息是这样的 Error
  • Caret 和 GBM:任务 1 失败 - “参数意味着行数不同”

    我正在尝试使用以下代码运行带插入符号的 GBM library caret library doParallel detectCores registerDoParallel detectCores 1 set seed 668 in tr
  • 有条件地为 R 中置信带之外的数据点着色

    我需要对下图中置信带之外的数据点与带内的数据点进行不同的着色 我是否应该在数据集中添加一个单独的列来记录数据点是否在置信区间内 您能举个例子吗 示例数据集 Dataset from http www apsnet org education
  • R数据表:将行值与组值进行比较,有条件

    这是问题的延伸 R数据表 将行值与组值进行比较 https stackoverflow com questions 33285050 r data table compare row value to group values 我现在有了

随机推荐

  • 在 Python 中将 NLTK 语料库与 AWS Lambda 函数结合使用

    我在 AWS Lambda 中使用 NLTK 语料库 特别是停用词 时遇到困难 我知道需要下载语料库 并且已使用 NLTK download stopwords 完成此操作 并将它们包含在用于上传 nltk data corpora sto
  • R 中频率为 10 分钟的时间序列

    我的数据是应用程序在过去 26 天内每 10 分钟间隔的内存消耗情况 我的开始日期是 2013 年 10 月 6 日 结束日期是 2013 年 11 月 2 日 我已将数据读入某个时间范围并将其清理 现在我正在尝试创建一个时间序列 类似于m
  • 我可以移动 UIAlertView 吗?

    我已经将警报视图稍微移高了一点 这样我也可以在屏幕上安装键盘 我只是通过抓取警报的框架并在显示警报后更改 Y 来做到这一点 以便框架变量是合法的 这在模拟器上运行良好 但是当我在硬件上执行此操作时 警报从正确的位置开始 但几乎立即跳到原来的
  • Windows 命令行 tar “无法连接到 d:解析失败” 使用 Chef Knife

    使用 Windows 命令行并安装了 cygwin chef 和 ruby 当尝试时 knife cookbook site install mysql 返回以下错误 Begin output of tar zxvf D path to c
  • 如何在 Python 中刷新网络驱动器映射

    我有一个驱动器已映射到指定字母 R 如果我在登录或解锁计算机的情况下运行 python 脚本来访问此空间 则它可以正常工作 当我将任务计划程序设置为在早上进来之前运行脚本时 就会出现问题 基本上 我保持登录状态并锁定机器 但在某些时候 我的
  • 将 numpy 指针 (dtype=np.bool) 传递给 C++

    我想通过 Cython 传递指针来使用 C 中 bool 类型的 numpy 数组 我已经知道如何使用 uint8 等其他数据类型来完成此操作 以与布尔值相同的方式执行此操作是行不通的 我能够编译 但在运行时出现以下异常 Traceback
  • Green Dao 无法初始化 DAOConfig

    我尝试使用一个旧的android应用程序 它使用Green Dao 例如我们的数据库 这个应用程序也有一个味道 所以我编译并安装了apk 但是应用程序无法启动 它给出了这个异常 Process com xxxx boeufaujardin
  • JS:递归调用promise函数

    我正在制作一个可以创建图像缩略图的node js 应用程序 为了避免在生成缩略图时冻结应用程序 我决定使用异步library https github com honza node thumbnail用于创建缩略图 然而 根据图像的不同 可
  • angular2:如何使用可观察量来消除窗口抖动:调整大小

    所以我试图找出一种方法来消除窗口 使用可观察量调整事件大小 因此只有在用户停止调整窗口大小或经过一段时间而没有大小变化 例如1秒 后才会调用某种函数 https plnkr co edit cGA97v08rpc7lAgitCOd http
  • 在 VC2015 中连接不匹配的字符串有效 - 如何?

    当我们有以下任一情况时 auto city1 New L Delhi auto city2 L New York 任何 VS2015 之前的编译器都会引发错误 错误 C2308 连接不匹配的字符串 但是用VC2015编译器 它编译得很好 结
  • 即使我安装了较新的版本,IDLE 仍会针对旧的 TCL 版本发出警告

    我已经安装了ActiveTcl8 6 1 1 297588 macosx10 5 i386 x86 64 threaded在我的 OS X 10 9 1 上 但是 当我通过运行启动 IDLE 时idle3从终端 IDLE 窗口中显示以下警告
  • iTextSharp PDF 打印

    我正在尝试创建一种方法 将 PDF 文件直接发送到我的打印机 导致出现打印对话框 下面是我一直在研究的代码 大部分是在论坛中找到的here https stackoverflow com questions 270674 print pdf
  • cordova 运行 android 失败,并显示 com.android.dex.DexIndexOverflowException: 方法 ID 不在 [0, 0xffff]: 65536

    这几天我一直无法跑步cordova run android 更确切地说 ionic run android 在我的本机设备上测试我的 Ionic 应用程序 当我运行该命令时 我得到了通常的公吨输出 以及几个 Java 运行时进程的 100
  • Facebook Graph API:参与计数细分

    使用旧的 API 我能够获取每个 URL 点赞 分享 评论 点击数 使用了links getStats urls www google com 如何通过新 API 获取所有这些信息 我尝试使用https graph facebook com
  • 尽管视图的 post() 出现错误,Django 测试客户端 post() 返回 302

    我目前正在编写一些基本测试 以确保中型 Django 应用程序中的页面正确获取和发布 然而 使用 django test client Client 并不会在应该失败的时候可靠地失败 即使我的代码中明显存在错误 它也会返回 302 响应 在
  • 如何在 Rails 中自动将所有链接设置为 nofollow

    我知道我可以通过 rel gt nofollow to link to但有没有一种方法可以默认设置 这样我就不必在每个中进行更改link to tag 在您的应用程序助手中 您可以覆盖link to方法并替换为您自己的 def link t
  • C switch 语句的汇编 - 它是如何工作的?

    我正在读一本关于汇编 switch 语句的书 当输入 n 为 case 100 102 103 104 106 时 代码有 case branch 它通过从 n 中减去 100 来简化跳转表 然后如果结果是上面的6 进入L2中的默认情况 否
  • mp3 文件的时间长度

    确定给定 mp3 文件的长度 以秒为单位 的最简单方法是什么 不使用外部库 高度赞赏Python源代码 您可以使用pymad http spacepants org src pymad 它是一个外部库 但不要陷入 Not Invented
  • Scala 中的地图内的地图

    我有这个代码 val total ListMap String HashMap Int val hm1 new HashMap Int String val hm2 new HashMap Int Int insert values in
  • 在 R 中查找矩阵的相邻元素

    编辑 非常感谢以下用户的巨大贡献以及 Gregor 的基准测试 假设我有一个充满整数值的矩阵 如下所示 mat lt matrix 1 100 10 10 我可以像这样创建每个元素的 x y 坐标列表 addresses lt expand