所以我知道要确定每行中第一次出现的特定元素,你使用带有which.max或which.min的apply函数。这是我现在使用的代码。
x <- matrix(c(20,9,4,16,6,2,14,3,1),nrow=3)
x
apply(3 >= x,1,which.max )
这产生和输出:
[1] 1 3 2
现在当我尝试在不同的矩阵“x2”
上做同样的事情时x2 <- matrix(c(3,9,4,16,6,2,14,3,1),nrow=3)
x2
apply(3 >= x2,1,which.max )
输出相同;
[1] 1 3 2
但对于“x2”,它是正确的,因为“x2”矩阵的第一行的值小于或等于三。
现在我的问题可能很简单,为什么apply函数为“x”和“x2”生成相同的东西。对于下面的“x”,我想要的是:
[1] 0 3 2
或者甚至可能是这样的:
[1] NA 3 2
我在堆栈溢出之前已经看到过关于.max没有生成NA的问题,答案是只使用which()函数,但是由于我使用的是矩阵而我想要第一次出现我没有那么奢侈... 我认为。
答案 0 :(得分:1)
我们可以用非常小的数字替换'x'中的值>&gt; 3,例如-999或低于数据集中最小值的值。使用which.max
获取替换向量的索引,并乘以逻辑索引来处理只有负值的情况。即在'x'的情况下,第一行都大于3.因此,用-999
代替which.max
返回1
作为索引,但我们更愿意拥有它{ {1}}或NA
。通过使用0
,第一行将为“0”并且否定(sum(x1>0
),它将转换为!
,再次否定并返回FALSE。将逻辑索引强制转换为二进制(0/1),我们得到第一种情况的'0'值。
TRUE
另一种选择是使用 apply(x, 1, function(x) {x1 <- ifelse(x>3, -999, x)
which.max(x1)*(!!sum(x1>0))})
#[1] 0 3 2
apply(x2, 1, function(x) {x1 <- ifelse(x>3, -999, x)
which.max(x1)*(!!sum(x1>0))})
#[1] 1 3 2
max.col
或稍作修改
x1 <- replace(x, which(x>3), -999)
max.col(x1)*!!rowSums(x1>0)
#[1] 0 3 2
x2N <- replace(x2, which(x2>3), -999)
max.col(x2N)*!!rowSums(x2N>0)
#[1] 1 3 2
答案 1 :(得分:0)
在&#39;(3&gt; = x)&#39;前面放一列这是无限,当且仅当相应行中的所有条目都是&#39; x&#39;大于3,否则NaN。然后申请&#39; which.max&#39; rowwise,最后减去1,因为有额外的列:
x <- matrix(c(20,9,4,16,6,2,14,3,1),nrow=3)
a <- (!apply(3>=x,1,max))*Inf
apply( cbind(a,3>=x), 1, which.max ) - 1
这给出了&#39; 0,3,2&#39; &#39; which.max&#39;应用于扩展矩阵
> cbind(a,3>=x)
a
[1,] Inf 0 0 0
[2,] NaN 0 0 1
[3,] NaN 0 1 1