简体   繁体   English

如何从变量中获取第一个和最后一个非Inf、非NaN、非NA、非0值?

[英]How to get the first and last non-Inf, non-NaN, non-NA, non-0 value from the variable?

Here is my toy dataset:这是我的玩具数据集:

    df <- tibble::tribble(
   ~data, ~first_non_0, ~last_non_0,
       0,         100,        430,
NA_real_,         100,        430,
     NaN,         100,        430,
     Inf,         100,        430,
     100,         100,        430,
     120,         100,        430,
     430,         100,        430,
     NaN,         100,        430,
     Inf,         100,        430,
       0,         100,        430,
NA_real_,         100,        430)

I want to get the我想得到

  1. First non-zero, non-NA, non-NaN, non-Inf value as shown in 2nd column第一个非零、非 NA、非 NaN、非 Inf 值,如第 2 列所示
  2. Last non-zero, non-NA, non-NaN, non-Inf value as shown in 3rd column最后一个非零、非 NA、非 NaN、非 Inf 值,如第 3 列所示

Inspired by this answer , I tried something like this, but not sure how to handle NaN and Inf:受此答案的启发,我尝试了类似的方法,但不确定如何处理 NaN 和 Inf:

df %>% 
  mutate(first = na_if(data, 0) %>% 
           na_if(data, NaN) %>% 
           na_if(data, Inf) %>% 
           na.omit() %>% 
           dplyr::first(),
         last  = na_if(data, 0) %>% 
           na_if(data, NaN) %>% 
           na_if(data, Inf) %>% 
           na.omit() %>%
           dplyr::last())

If all your values are positive, you can use df$data > 0 as a condition and then you only have to handle Infinite , ie如果您的所有值都是正数,则可以使用df$data > 0作为条件,然后您只需要处理Infinite ,即

i1 <- which(df$data > 0 & !is.infinite(df$data))

df$data[i1[1]]
#[1] 100
df$data[i1[length(i1)]]
#[1] 430

In case you also have negative values, you can switch the condition from greater than, to not-equal, (compliment of @markus)如果您也有负值,您可以将条件从大于切换到不等于(@markus 的赞美)

i1 <- which(df$data != 0 & !is.infinite(df$data))

Another option:另外的选择:

f <- function(x) {
  cond <- x != 0 & !is.na(x) & is.finite(x) & !is.nan(x)
  tmp <- x[cond]
  as.list(tmp[c(1, length(tmp))])
}

Note : that condition can be simplified, see @Sotos answer .注意:该条件可以简化,请参阅@Sotos 答案

Apply the function to that column and insert the values as new columns将 function 应用于该列并将值作为新列插入

df[, c("var1", "var2")] <- f(df$data)

Result结果

df
# A tibble: 11 x 5
#    data first_non_0 last_non_0  var1  var2
#   <dbl>       <dbl>      <dbl> <dbl> <dbl>
# 1     0         100        430   100   430
# 2    NA         100        430   100   430
# 3   NaN         100        430   100   430
# 4   Inf         100        430   100   430
# 5   100         100        430   100   430
# 6   120         100        430   100   430
# 7   430         100        430   100   430
# 8   NaN         100        430   100   430
# 9   Inf         100        430   100   430
#10     0         100        430   100   430
#11    NA         100        430   100   430

Taking clues from is.finite used by @Sotos and @markus and their discussion, I checked this and got the answer.从@Sotos 和@markus 使用的is.finite 以及他们的讨论中获取线索,我检查了这个并得到了答案。 Thanks to both of you!感谢你们俩!

is.finite(c(NA_real_, NaN, Inf))

df %>% 
  mutate(first = na_if(data, 0),
         first = if_else(is.finite(first), first, NA_real_),
         first = first(na.omit(first))) %>% 
  mutate(last = na_if(data, 0),
         last = if_else(is.finite(last), last, NA_real_),
         last = last(na.omit(last)))

Result:结果:

# A tibble: 11 x 5
    data first_non_0 last_non_0 first  last
   <dbl>       <int>      <int> <dbl> <dbl>
 1     0         100        430   100   430
 2    NA         100        430   100   430
 3   NaN         100        430   100   430
 4   Inf         100        430   100   430
 5   100         100        430   100   430
 6   120         100        430   100   430
 7   430         100        430   100   430
 8   NaN         100        430   100   430
 9   Inf         100        430   100   430
10     0         100        430   100   430
11    NA         100        430   100   430

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM