我有以下数据帧,
a1=c(9,8,rep(NA,5))
a2=c(3,NA,3,NA,3,NA,4)
a3=c(11,6,7,NA,5,NA,NA)
k<-as.data.frame(rbind(a1,a2,a3))
我想添加一列,指示从第一个到最后一个非NA值的列数。也就是说,对于第一行,这个附加列中的值将是2,对于第二行,它将是7,对于最后一行,它是5。
我们可以在行(apply
和MARGIN = 1
(上循环,得到非NA元素的索引(which
+!is.na
(,提取min/max
(range
(,取diff
差值`并添加1个
k$new <- apply(k, 1, function(x) {
i1 <- which(!is.na(x))
i2 <- diff(range(i1))
i2 + 1 })
或者使用max.col
作为矢量化方法。将数据转换为逻辑矩阵,应用max.col
和ties.method
作为first
和last
,以获得每行中第一个或最后一个最大值(TRUE
->1和FALSE
->0(的位置。由于它是一个逻辑矩阵,这基本上是在每行中寻找第一个和最后一个TRUE位置,减去和加1
max.col(!is.na(k), "last") - max.col(!is.na(k), "first") + 1
[1] 2 7 5
这也可以在tidyverse
:中完成
library(dplyr)
library(purrr)
k %>%
mutate(new = pmap(k, ~ {x <- which(!is.na(c(...)))
y <- max(x) - min(x) + 1
y}))
V1 V2 V3 V4 V5 V6 V7 new
a1 9 8 NA NA NA NA NA 2
a2 3 NA 3 NA 3 NA 4 7
a3 11 6 7 NA 5 NA NA 5
还有这个:
k %>%
rowwise() %>%
mutate(new = {x <- which(!is.na(c_across(everything())))
range(x)[2] - range(x)[1] + 1})
# A tibble: 3 x 8
# Rowwise:
V1 V2 V3 V4 V5 V6 V7 new
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 9 8 NA NA NA NA NA 2
2 3 NA 3 NA 3 NA 4 7
3 11 6 7 NA 5 NA NA 5