如何从变量中获取第一个和最后一个非 Inf、非 NaN、非 NA、非 0 的值?
How to get the first and last non-Inf, non-NaN, non-NA, non-0 value from the variable?
这是我的玩具数据集:
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)
我想得到
- 第一个非零、非 NA、非 NaN、非 Inf 值,如第 2 列所示
- 最后一个非零、非 NA、非 NaN、非 Inf 值,如第 3 列所示
受到的启发,我尝试了类似的方法,但不确定如何处理 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())
如果你所有的值都是正数,你可以使用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
如果您也有负值,则可以将条件从大于切换为不等于(@markus 的赞美)
i1 <- which(df$data != 0 & !is.infinite(df$data))
另一个选项:
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))])
}
注:那个条件可以简化,见。
将该函数应用于该列并将值作为新列插入
df[, c("var1", "var2")] <- f(df$data)
结果
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
从@Sotos 和@markus 使用的 is.finite 和他们的讨论中获取线索,我检查了这个并得到了答案。谢谢你们!
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)))
结果:
# 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
这是我的玩具数据集:
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)
我想得到
- 第一个非零、非 NA、非 NaN、非 Inf 值,如第 2 列所示
- 最后一个非零、非 NA、非 NaN、非 Inf 值,如第 3 列所示
受到
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())
如果你所有的值都是正数,你可以使用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
如果您也有负值,则可以将条件从大于切换为不等于(@markus 的赞美)
i1 <- which(df$data != 0 & !is.infinite(df$data))
另一个选项:
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))])
}
注:那个条件可以简化,见
将该函数应用于该列并将值作为新列插入
df[, c("var1", "var2")] <- f(df$data)
结果
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
从@Sotos 和@markus 使用的 is.finite 和他们的讨论中获取线索,我检查了这个并得到了答案。谢谢你们!
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)))
结果:
# 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