r - 有效地找到数据表的第一个非零元素(对应列)
问题描述
对于以下类型的问题,堆栈上有一些答案,但它们都效率低下并且不能很好地扩展。
要重现它,假设我的数据如下所示:
tempmat=matrix(c(1,1,0,4,1,0,0,4,0,1,0,4, 0,1,1,4, 0,1,0,5),5,4,byrow=T)
tempmat=rbind(rep(0,4),tempmat)
tempmat=data.table(tempmat)
names(tempmat)=paste0('prod1vint',1:4)
这就是数据的样子,尽管它要大得多,因此解决方案不能是“应用”或基于行的方法。
> tempmat
prod1vint1 prod1vint2 prod1vint3 prod1vint4
1: 0 0 0 0
2: 1 1 0 4
3: 1 0 0 4
4: 0 1 0 4
5: 0 1 1 4
6: 0 1 0 5
我想识别第一个非零元素的列,因此输出如下所示:
> tempmat
prod1vint1 prod1vint2 prod1vint3 prod1vint4 firstnonzero
1: 0 0 0 0 NA
2: 1 1 0 4 1
3: 1 0 0 4 1
4: 0 1 0 4 2
5: 0 1 1 4 2
6: 0 1 0 5 2
解决方案
一种选择是rowSums
与max.col
指定一起使用ties.method = "first"
temp <- tempmat != 0
(NA^(rowSums(temp) == 0)) * max.col(temp, ties.method = "first")
#[1] NA 1 1 2 2 2
max.col
将给出每行中第一个最大值的列索引。但是,如果所有值都是 0(如第一行),这将返回 1,因为 0 是该行中的最大值。为避免这种情况,我们使用检查行中是否至少有一个非零值rowSums
并将其相乘以max.col
输出。
推荐阅读
- scala - 使用 scala 进程构建器语法错误的 psql \copy 命令
- statistics - 使用`pyhf`浮动信号和背景强度
- php - 如何从 WooCommerce 中的返回 URL 中提取 JSON 密钥以进行身份验证
- kotlin - 如何从 Kotlin 中的匿名 lambda 返回?
- javascript - 开玩笑的模拟函数没有调用模拟的 axios 实例函数(返回未定义)
- openshift - Keycloak WFLYCTL0362:资源所需的功能
- git - 使用 GIT 如何将不同提交中的文件签出到新分支中?
- python - 设置 numpy 时如何解决此错误?
- python - 如何获取页面上所有图像的列表?
- android - android读取视频OutOfMemoryError