我有一个大型矩阵“dt”的急诊部门访问超过2个月的一组诊断代码。列是“年龄”,“性别”,“日期”,“县”,“拉链”,“主观”,“位置”,“诊断”和“dt”;尺寸为872344×9。
我想从这个矩阵中进行子集化,并创建一个新的矩阵,其中只包含“diag”列的数字介于800和849之间(所有列)的行。
我一直在搞乱构建循环并使用“which”或“if.else”,但我遇到了一个心理障碍。看起来如果它只是一个我想要提取的诊断代码会更容易,但50个代码的系列使事情变得复杂......指向一个循环?有没有人有基于找到某些值的子集的想法?
这是我的开始(它不起作用):
dta = dt
b = 800:849
for (i in 1:length(b)) {
}
答案 0 :(得分:6)
dta = dt[dt[, 8] >= 800 & dt[, 8] <= 849, ]
ETA:你确定这是一个矩阵而不是data.frame吗?如果是data.frame,您可以执行以下操作:
dta = dt[dt$diag >= 800 & dt$diag <= 849, ]
答案 1 :(得分:5)
根据你的列名,我怀疑你的dt
是一个data.frame,而不是一个矩阵;您可以通过运行is.data.frame(dt)
来确认。
如果是这种情况,过滤数据的简便方法是使用subset
函数,如下所示:
dta <- subset(dt, diag >= 800 & diag <= 849)
答案 2 :(得分:0)
除了上面的优秀答案,我还可以在message = openpgp.message.readArmored (message);
包中添加filter
功能
dpylr
filter(dt,diag>=800 & diag <= 849)
与filter()
类似,不同之处在于您可以为其提供任意数量的过滤条件,这些过滤条件与subset()
(非&
一起使用很容易偶然!)。 &&
包还有其他很好的数据操作函数,您可以查看。
答案 3 :(得分:0)
我不会将matrix()
转换为data.frame()
,因为它较慢并且会占用更多内存,而matrix()
操作通常会更快。
除了David的回答,使用列号索引:
dta = dt[dt[,8] >= 800 & dt[,8] <= 849,]
还有一个使用列名称索引的表单和矩阵:
dta = dt[dt[,'metric'] >= 800 & dt[,'metric'] <= 849,]
如microbenchmark
包命令所示,对于包含12列和13,241行的相同矩阵,使用英特尔MKL优化编译的R运行:
microbenchmark::microbenchmark(
test.matrix = mt[mt[,3] %in% 5:10 & mt[,5] == 1,],
test.data.frame = df[df[,3] %in% 5:10 & df[,5] == 1,],
times = 1000
)
Unit: microseconds
expr min lq mean median uq max neval
test.matrix 885.732 938.386 1154.898 943.74 952.4415 138215.318 1000
test.data.frame 1176.218 1245.826 1363.379 1258.32 1286.4320 3392.556 1000
当矩阵变得非常大时,这种差异变得明显。在我的机器上,矩阵索引速度也优于data.table
。