我正在尝试对R中数据表的每个单元格执行一个函数,根据此循环的结果创建第二个单元格。例如,假设我有矩阵A
Ad1 Ad2 Ad3 Ad4
AA 6 0 10
AB 7 10 12
AC 0 0 15
我正在尝试创建Matrix B
Ad1 Ad2 Ad3 Ad4
AA 1 0 1
AB 1 0 1
AC 0 0 1
以每个单元格的值为1的方式,如果该单元格具有值> 0 AND 列减去该单元格的总和也大于0.
例如,AA~Ad2为6,列的总和为7(6 + 7 + 0 - 6);然后矩阵B中的AA~Ad2假设值为1。
有没有办法在不执行循环的情况下执行此操作?我已经设法通过一个循环来做到这一点,但它花了太长时间:
A = read.table(text="Ad1 Ad2 Ad3 Ad4
AA 6 0 10
AA 7 10 12
AA 0 0 15", header=TRUE)
B = read.table(text="Ad1 Ad2 Ad3 Ad4
AA 0 0 0
AA 0 0 0
AA 0 0 0", header=TRUE)
for (i in 1:nrow(B)) {
for (j in 2:ncol(B)) {
if ((sum(A[,j], na.rm = T) - ifelse(is.na(A[i,j]), 0, A[i,j]))> 0 &
ifelse(is.na(A[i,j]), 0, A[i,j]) > 0 )
{B[i,j] <- 1}
}
}
答案 0 :(得分:6)
我们可以通过创建两个逻辑矩阵而无需循环来执行此操作-1)检查数字列值是否大于0(A[-1] > 0
),2)检查列的总和是否与列值相加也大于0.如果它们都为TRUE(&
条件),则将逻辑矩阵转换为二进制(+
)并将其分配给数据集的子集(A[-1]
)
A[-1] <- +(colSums(A[-1])[col(A[-1])]-A[-1]>0 & A[-1] > 0)
A
# Ad1 Ad2 Ad3 Ad4
#1 AA 1 0 1
#2 AB 1 1 1
#3 AC 0 0 1
答案 1 :(得分:1)
以下是2行中的替代基本R方法。第一个拉出矩阵,这可能会减少复制。第二行计算结果,首先检查值是否大于0,然后检查总colSum是否大于每个元素。这一部分部分通过rep
与每个参数完成。
# extract matrix from data.frame
myMat <- as.matrix(A[-1])
# calculate result and store in data.frame
A[-1] <- (myMat > 0) * ((rep(colSums(myMat), each=nrow(myMat))- myMat) > 0)
A
Ad1 Ad2 Ad3 Ad4
1 AA 1 0 1
2 AA 1 0 1
3 AA 0 0 1
答案 2 :(得分:1)
这是一个使用在原始矩阵上评估的两个逻辑表达式的解决方案:
00 03 * * * <pathtomyscript>/myscript.sh
(A > 0 & (colSums(A) - A > 0)) * 1.0
的左侧检查值是否大于零,而右侧检查与列总和相关的要求。
它们本身就产生了与&
相同维度的逻辑矩阵。 A
然后允许您组合逻辑矩阵以生成一个新的单元格,只有当两个输入矩阵中的单元格都为TRUE时,单元格才为TRUE。
最后,&
将逻辑矩阵转换为数字。
答案 3 :(得分:0)
你也可以这样做:
m <- as.matrix(A[,-1])
colsm <- matrix(colSums(m), ncol = ncol(m), nrow = nrow(m), byrow = T)
(colsm-m)>0 & m>0)*1
# Ad2 Ad3 Ad4
#[1,] 1 0 1
#[2,] 1 0 1
#[3,] 0 0 1