在数据框中按列查找最后一个缺失值

时间:2015-04-10 22:27:13

标签: r dataframe na

我有一个数据框,例如:

> set.seed(8)

> A <- rnorm(10, 20)
> B <- rnorm(10, 45)
> C <- rnorm(10, 60)

> test1 <- data.frame(A,B,C)
> test1 <- round(test1, digits = 2)

> test1[sample(1:10, 3, F), 1] <- NA
> test1[sample(1:10, 3, F), 2] <- NA
> test1[sample(1:10, 3, F), 3] <- NA

> test1[11:20, ] <- NA
> test1$date <- seq.Date(from = as.Date('1970-01-01', origin='01-01-1970'),
                   to = as.Date('1970-01-20', origin='01-01-1970'), by=1)
> test1
       A     B     C       date
1  19.92    NA 61.28 1970-01-01
2  20.84 45.29    NA 1970-01-02
3  19.54 45.42    NA 1970-01-03
4  19.45 43.71 60.02 1970-01-04
5  20.74 45.07 61.74 1970-01-05
6  19.89 44.19 58.89 1970-01-06
7     NA    NA 58.94 1970-01-07
8  18.91 44.73    NA 1970-01-08
9     NA    NA 60.60 1970-01-09
10    NA 44.76 57.98 1970-01-10
11    NA    NA    NA 1970-01-11
12    NA    NA    NA 1970-01-12
13    NA    NA    NA 1970-01-13
14    NA    NA    NA 1970-01-14
15    NA    NA    NA 1970-01-15
16    NA    NA    NA 1970-01-16
17    NA    NA    NA 1970-01-17
18    NA    NA    NA 1970-01-18
19    NA    NA    NA 1970-01-19
20    NA    NA    NA 1970-01-20

所以最后有很多NANA&#34;尾巴&#34;),人们可能想要消除。我已经尝试找到第一个NA,但我会在数据框的中间碰到NA

 > apply(test1, 2, function(x) which(is.na(x))[1])
   A    B    C date 
   7    1    2   NA 
 > test1$A[8] #As you can see this doesn't give me what I need.
 [1] 18.91

complete.cases()函数无法提供帮助,因为我不想删除所有缺少值的行。反转数据框并检索第一个非NA应该是这里的方法:

> apply(test1[nrow(test1):1, ], 2, function(x) which(!is.na(x))[1])

   A    B    C date 
  13   11   11    1 

在此之后,应使用编号最小的列来查找包含最后一个非完全NA行的行号。这导致:

> test1[1:(nrow(test1)-10), ]

这将产生一个没有长尾丢失值的数据帧。虽然这有效,但我认为有更好/更快的方法来实现这一目标。我会写一个函数并等待答案。

2 个答案:

答案 0 :(得分:0)

> colaVA <- function(x){
>   mat <- apply(x[nrow(test1):1, ], 2, function(x) which(!is.na(x))[1])
>   n <- length(mat)
>   m <- sort(mat, partial=n-1)[n-1]
>   x <- x[1:(m-1),]
>  x
> }
> 
> colaVA(test1)

       A     B     C       date
1  19.92    NA 61.28 1970-01-01
2  20.84 45.29    NA 1970-01-02
3  19.54 45.42    NA 1970-01-03
4  19.45 43.71 60.02 1970-01-04
5  20.74 45.07 61.74 1970-01-05
6  19.89 44.19 58.89 1970-01-06
7     NA    NA 58.94 1970-01-07
8  18.91 44.73    NA 1970-01-08
9     NA    NA 60.60 1970-01-09 
10    NA 44.76 57.98 1970-01-10

答案 1 :(得分:0)

您可以在指标上使用rle(游程编码)来确定是否缺少值来标识每列中最后一个非NA值的行号:

apply(test1, 2, function(x) {r <- rle(is.na(x)) ; cumsum(r$length)[max(which(!r$value))]})
#    A    B    C date 
#    8   10   10   20 

然后你可以根据这些值来选择你认为合适的子集。