R 如何根据逻辑从数字矩阵生成向量或因子(循环为否)
我有一个30000行3列的数字矩阵。我想根据矩阵每行中的3个值生成一个简单的通过/失败向量(或因子)。我想应用以下逻辑: 如果第3行中的所有3个值均大于3,则输入PASS,否则输入FAIL 我知道如何使用for循环来实现这一点,但我如何才能更快地实现它?我有几十个这样的矩阵。。。谢谢大家!R 如何根据逻辑从数字矩阵生成向量或因子(循环为否),r,vector,matrix,R,Vector,Matrix,我有一个30000行3列的数字矩阵。我想根据矩阵每行中的3个值生成一个简单的通过/失败向量(或因子)。我想应用以下逻辑: 如果第3行中的所有3个值均大于3,则输入PASS,否则输入FAIL 我知道如何使用for循环来实现这一点,但我如何才能更快地实现它?我有几十个这样的矩阵。。。谢谢大家! as.矩阵(rbind(c(129120),c(135,97,96),c(0,0,0),c(39,4,2)) 期望输出: 通过,通过,失败,失败库(data.table) library(data.table
as.矩阵(rbind(c(129120),c(135,97,96),c(0,0,0),c(39,4,2))
期望输出:
通过,通过,失败,失败库(data.table)
library(data.table)
dt <- as.matrix(rbind(c(129,129,120),c(135,97,96),c(0,0,0),c(39,4,2)))
dt <- data.table(dt)
dt[, Indicator :="FAIL"]
dt[V1 > 3 & V2 >3 & V3 >3, Indicator :="PASS" ]
dt 3和V3>3,指示器:=“通过”]
使用all
和apply
(尽管apply
使用自己的循环)
稍微扩展一下Codoremifa的答案,类似的方法也适用于
data.table
,特别是当您指定想要一个向量或因子作为输出时
library(data.table)
DT <- data.table(m)
DT[, all(.SD > 3), by = 1:nrow(DT)][, factor(V1, labels = c("FAIL", "PASS"))]
# [1] PASS PASS FAIL FAIL
# Levels: FAIL PASS
库(data.table)
DT 3),by=1:nrow(DT)][,系数(V1,标签=c(“失败”,“通过”))]
#[1]通过失败
#等级:不合格
对于这样的问题,我的第一个倾向是结合起来,&,也许就像@Ananda提供的解决方案一样。正如他提到的,apply()
正在使用循环。如果需要完全矢量化的解决方案,可以尝试:
newVector <- ifelse((xMatrix[,1]>3 & xMatrix[,2]>3 & xMatrix[,3]>3),
"PASS", "FAIL")
newVector 3&xMatrix[,2]>3&xMatrix[,3]>3),
“通过”、“失败”)
矢量化是R的一个方便的特性,它比循环快得多。您可以阅读有关矢量化的内容 此外,
mapply
:
mat <- as.matrix(rbind(c(129,129,120),c(135,97,96),c(0,0,0),c(39,4,2)))
fun <- function(x, y, z) { ifelse(x > 3 & y > 3 & z > 3, "PASS", "FAIL") }
mapply(fun, mat[,1], mat[,2], mat[,3])
#[1] "PASS" "PASS" "FAIL" "FAIL"
mat 3&z>3,“通过”、“失败”)}
mapply(fun,mat[,1],mat[,2],mat[,3])
#[1] “通过”“通过”“失败”“失败”
与这里的其他答案不同,它使用了行和
,但这不会在R中循环,并且可以超过多个子集和逻辑。这可能是最快的路线
mat <- as.matrix(rbind(c(129,129,120),c(135,97,96),c(0,0,0),c(39,4,2)))
vec <- ifelse(rowSums(mat > 3) == 3, TRUE, FALSE)
如果你测试这些时间,那可能是赢家。在我的系统中,使用30000行矩阵,我的第一个答案出来的速度大约是gung答案的两倍,第二个答案出来的速度是gung答案的10倍,可以在大约2秒钟内对1000 30000行矩阵执行。Codoremifa答案是最快的数据。这里基于表的答案,需要20秒(与gung答案类似)
注意:我有点忽略了您对“通过”、“失败”向量的请求,因为您似乎表示速度是最重要的,而且这只是一个微不足道的语义区别。此外,如果需要,逻辑向量已经准备好对矩阵进行子集划分。这正是我想要的,你是对的,通过/失败只是一个想法。不知道逻辑向量,非常有用!谢谢-我使用了2线解决方案blazing@Stefan,我相信你只需要一行代码就可以做到这一点:rowSums(m>3)=ncol(m)
。对……更新了答案,因为最初我用PASS/FAIL编写的东西没有完全转换,但是……为什么要使用ncol?@John,这只是一种自动化的方式(所以我们不必首先计算原始矩阵中有多少列).我要感谢所有在这里回答的人!很抱歉,我没有更准确地描述通过/失败-我知道有些解决方案是为了使输出符合要求而编写的。感谢您花时间回答,我学习了向量化函数、逻辑向量、ifelse和apply。进行stackexchange总是一个好主意。谢谢大家!!我认为data.table结构非常简洁,但我设置了500000行data.table
,这需要很长时间。是因为“by”吗?有解决办法吗?@Codoremifa,不太确定。到底有多长?:)<代码>>dt>系统时间(dt[V1>.7&V2>.7&V3>.7,指示器:=“通过”])用户系统运行时间0.14 0.00 0.14>系统时间(dt[,所有(.SD>.7),by=1:nrow(dt)],系数(V1,标签=c(“失败”,“通过”)])用户系统运行时间75.61 0.05 76.25
@Codoremifa,我猜这与逐行使用.SD
有关。看,但我还没有想到解决办法。
mat <- as.matrix(rbind(c(129,129,120),c(135,97,96),c(0,0,0),c(39,4,2)))
fun <- function(x, y, z) { ifelse(x > 3 & y > 3 & z > 3, "PASS", "FAIL") }
mapply(fun, mat[,1], mat[,2], mat[,3])
#[1] "PASS" "PASS" "FAIL" "FAIL"
mat <- as.matrix(rbind(c(129,129,120),c(135,97,96),c(0,0,0),c(39,4,2)))
vec <- ifelse(rowSums(mat > 3) == 3, TRUE, FALSE)
vec <- rowSums(mat > 3) == 3