删除最后一行数据框,直到到达没有 NA 的行
Remove last row of data frame until reaching a row that does not have an NA
我有一个包含 NA
值的数据框,我想删除一些具有 NA
的行(即,不完整的案例)。但是,我只想删除数据框末尾的行。所以,我想保留任何不在数据帧末尾的 NA
行。在不使用行索引的情况下删除带有 NA
的结尾行的最有效方法是什么?
数据
df <- structure(list(var1 = 1:15, var2 = c(3, 6, 3, NA, 2, NA, 3, 4,
2, NA, 4, 2, 45, 2, 1), var3 = c(6L, 7L, 8L, 9L, 10L, 11L, 12L,
13L, 14L, 15L, 16L, NA, NA, NA, NA), var4 = c(NA, 7L, 8L, 9L,
10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, NA)), class = "data.frame", row.names = c(NA,
-15L))
预期输出
所以,在这个例子中,我删除了第 12 到 15 行,因为它们有 NA
而第 11 行没有 NA
.
var1 var2 var3 var4
1 1 3 6 NA
2 2 6 7 7
3 3 3 8 8
4 4 NA 9 9
5 5 2 10 10
6 6 NA 11 11
7 7 3 12 12
8 8 4 13 13
9 9 2 14 14
10 10 NA 15 15
11 11 4 16 16
我可以 通过:
df[cumsum(complete.cases(df)) != 0,]
要删除最后一行,您可以在相同的方法中使用 rev
。因此,我们将 complete.cases
的输出倒序排列,这样我们就可以从数据帧的末尾开始计算 cumsum
。然后,我们将 cumsum
放回原来的顺序(第二个 rev
的原因)。现在,我们可以删除带有 0
的行(即包含 NA
的行)。
df[rev(cumsum(rev(complete.cases(df)))) != 0,]
或 dplyr
:
library(dplyr)
df %>%
filter(rev(cumsum(rev(complete.cases(.)))) != 0)
输出
var1 var2 var3 var4
1 1 3 6 NA
2 2 6 7 7
3 3 3 8 8
4 4 NA 9 9
5 5 2 10 10
6 6 NA 11 11
7 7 3 12 12
8 8 4 13 13
9 9 2 14 14
10 10 NA 15 15
11 11 4 16 16
我们可以使用 zoo
包中的 na.trim
:
library(zoo)
library(dplyr)
df %>%
slice(1:nrow(na.trim(df, "right", is.na = "any")))
var1 var2 var3 var4
1 1 3 6 NA
2 2 6 7 7
3 3 3 8 8
4 4 NA 9 9
5 5 2 10 10
6 6 NA 11 11
7 7 3 12 12
8 8 4 13 13
9 9 2 14 14
10 10 NA 15 15
11 11 4 16 16
折磨并且可能仅适用于最大值偶然与最后一行重合的这种情况:
df2[1:(length(df2[,1])-max(rle(complete.cases(df2))$lengths)),]
var1 var2 var3 var4
1 1 3 6 NA
2 2 6 7 7
3 3 3 8 8
4 4 NA 9 9
5 5 2 10 10
6 6 NA 11 11
7 7 3 12 12
8 8 4 13 13
9 9 2 14 14
10 10 NA 15 15
11 11 4 16 16
我有一个包含 NA
值的数据框,我想删除一些具有 NA
的行(即,不完整的案例)。但是,我只想删除数据框末尾的行。所以,我想保留任何不在数据帧末尾的 NA
行。在不使用行索引的情况下删除带有 NA
的结尾行的最有效方法是什么?
数据
df <- structure(list(var1 = 1:15, var2 = c(3, 6, 3, NA, 2, NA, 3, 4,
2, NA, 4, 2, 45, 2, 1), var3 = c(6L, 7L, 8L, 9L, 10L, 11L, 12L,
13L, 14L, 15L, 16L, NA, NA, NA, NA), var4 = c(NA, 7L, 8L, 9L,
10L, 11L, 12L, 13L, 14L, 15L, 16L, 17L, 18L, 19L, NA)), class = "data.frame", row.names = c(NA,
-15L))
预期输出
所以,在这个例子中,我删除了第 12 到 15 行,因为它们有 NA
而第 11 行没有 NA
.
var1 var2 var3 var4
1 1 3 6 NA
2 2 6 7 7
3 3 3 8 8
4 4 NA 9 9
5 5 2 10 10
6 6 NA 11 11
7 7 3 12 12
8 8 4 13 13
9 9 2 14 14
10 10 NA 15 15
11 11 4 16 16
我可以
df[cumsum(complete.cases(df)) != 0,]
要删除最后一行,您可以在相同的方法中使用 rev
。因此,我们将 complete.cases
的输出倒序排列,这样我们就可以从数据帧的末尾开始计算 cumsum
。然后,我们将 cumsum
放回原来的顺序(第二个 rev
的原因)。现在,我们可以删除带有 0
的行(即包含 NA
的行)。
df[rev(cumsum(rev(complete.cases(df)))) != 0,]
或 dplyr
:
library(dplyr)
df %>%
filter(rev(cumsum(rev(complete.cases(.)))) != 0)
输出
var1 var2 var3 var4
1 1 3 6 NA
2 2 6 7 7
3 3 3 8 8
4 4 NA 9 9
5 5 2 10 10
6 6 NA 11 11
7 7 3 12 12
8 8 4 13 13
9 9 2 14 14
10 10 NA 15 15
11 11 4 16 16
我们可以使用 zoo
包中的 na.trim
:
library(zoo)
library(dplyr)
df %>%
slice(1:nrow(na.trim(df, "right", is.na = "any")))
var1 var2 var3 var4
1 1 3 6 NA
2 2 6 7 7
3 3 3 8 8
4 4 NA 9 9
5 5 2 10 10
6 6 NA 11 11
7 7 3 12 12
8 8 4 13 13
9 9 2 14 14
10 10 NA 15 15
11 11 4 16 16
折磨并且可能仅适用于最大值偶然与最后一行重合的这种情况:
df2[1:(length(df2[,1])-max(rle(complete.cases(df2))$lengths)),]
var1 var2 var3 var4
1 1 3 6 NA
2 2 6 7 7
3 3 3 8 8
4 4 NA 9 9
5 5 2 10 10
6 6 NA 11 11
7 7 3 12 12
8 8 4 13 13
9 9 2 14 14
10 10 NA 15 15
11 11 4 16 16