R -找出向量中的最小值,但不能是0



我的df是这样的

  df <- data.frame(t1 = c(10, 20, 30, 1, 0), t2 = c(30, 0, 40, 0, 0), t3 = c(10, 0, 3, 10, 0))

我要做的是在df行中找到min,但不是0我做

df<- df%>% rowwise() %>%
  do({
    th <- c(.$t1, .$t2, .$t3,)

    data.frame(., t_s_last = min(th[th > 0))
  })

,但它的工作,但不是为包含STH大于0的行。如果行(第5行)中只有0,如何使此返回0 ?

我们可以在if/else条件下使用apply

 apply(df, 1, function(x) if(all(x==0)) 0 else min(x[x> 0]))

或者另一个选项是library(matrixStats)中的rowMins。我们将数据集中的'0'值替换为NA,将rowMins替换为na.rm=TRUE,并将'Inf'值替换为0。

 library(matrixStats)
 is.na(df) <- df==0
 v1 <- rowMins(as.matrix(df), na.rm=TRUE)
 v1[is.infinite(v1)] <- 0
 v1
 #[1] 10 20  3  1  0

我们也可以在do

中使用if/else
library(dplyr)
df %>%
    rowwise() %>%
    do({th <- unlist(.[.>0])
       data.frame(., t_s_last = if(all(th==0)) 0 else min(th))})
#  t1 t2 t3 t_s_last
#1 10 30 10       10
#2 20  0  0       20
#3 30 40  3        3
#4  1  0 10        1
#5  0  0  0        0

我猜,因为你正在寻找高于零的值,所有的值>=0和整数。因此,我们可以使用log变换,以便将所有的0转换为Inf,从而始终是最大的。这将帮助我们避免逐行操作,而是使用max.col函数

的减号进行矢量化。
df[cbind(1:nrow(df), max.col(-abs(log(df))))]
## [1] 10 20  3  1  0

这里是使用dplyrtidyr的另一种方法。比@akrun的回答长一点。但如果不使用do:

,可能会更具可读性
library(dplyr)
library(tidyr)
df %>%
  mutate(id = row_number()) %>%
  gather(time, value, t1:t3) %>%
  group_by(id) %>%
  mutate(ts = ifelse(all(value == 0), 0, min(value[value != 0])))  %>%
  spread(time, value)

最新更新