我有一个大型数据框,300多列(时间序列),大约有2600个观测值。列中填充了大量的NA,然后是短时间序列,然后通常再次使用NA。我想在每列中找到第一个非NA值,并用NA替换它。
这是我希望实现的目标,只有更大的数据框:
在:
x1 x2 x3 x4
1 NA NA NA NA
2 NA NA NA NA
3 1 1 NA NA
4 2 2 1 1
5 3 3 2 2
6 4 4 3 3
7 5 5 4 4
8 6 6 5 5
9 7 7 6 6
10 8 8 7 7
11 9 9 NA NA
12 10 10 NA NA
13 NA NA NA NA
14 NA NA NA NA
后:
x1 x2 x3 x4
1 NA NA NA NA
2 NA NA NA NA
3 NA NA NA NA
4 2 2 NA NA
5 3 3 2 2
6 4 4 3 3
7 5 5 4 4
8 6 6 5 5
9 7 7 6 6
10 8 8 7 7
11 9 9 NA NA
12 10 10 NA NA
13 NA NA NA NA
14 NA NA NA NA
我已经四处搜索并找到了为每个专栏执行此操作的方法,但我将其应用于整个数据框的努力已经证明是困难的。
我创建了一个示例数据框来重现我的原始数据帧:
#Dataframe with NA
x1=x2=c(NA,NA,1:10,NA,NA)
x3=x4=c(NA,NA,NA,1:7,NA,NA,NA,NA)
df=data.frame(x1,x2,x3,x4)
我用它来替换1列中的NA的第一个值(由@Joshua Ulrich here提供),但是我想将其应用于所有列而无需手动更改300+代码:
NonNAindex <- which(!is.na(df[,1]))
firstNonNA <- min(NonNAindex)
is.na(df[,1]) <- seq(firstNonNA, length.out=1)
我尝试将上面的内容设置为一个函数,然后使用apply
/ lapply
以及for
循环为所有列运行它,但确实没有想出了如何将更改应用到我的数据框。我确信有一件事我完全被忽略了,因为我只是在R中迈出了我的第一个小步骤。
所有建议都将受到高度赞赏!
答案 0 :(得分:5)
我们可以使用base R
df1[] <- lapply(df1, function(x) replace(x, which(!is.na(x))[1], NA))
df1
# x1 x2 x3 x4
#1 NA NA NA NA
#2 NA NA NA NA
#3 NA NA NA NA
#4 2 2 NA NA
#5 3 3 2 2
#6 4 4 3 3
#7 5 5 4 4
#8 6 6 5 5
#9 7 7 6 6
#10 8 8 7 7
#11 9 9 NA NA
#12 10 10 NA NA
#13 NA NA NA NA
#14 NA NA NA NA
或者@thelatemail建议
df1[] <- lapply(df1, function(x) replace(x, Position(Negate(is.na), x), NA))
答案 1 :(得分:1)
由于您希望对所有列执行此操作,因此您可以使用mutate_all
中的dplyr
函数。有关详细信息,请参阅http://dplyr.tidyverse.org/。特别是,您可能希望查看显示here的一些示例。
library(dplyr)
mutate_all(df, funs(if_else(row_number() == min(which(!is.na(.))), NA_integer_, .)))
#> x1 x2 x3 x4
#> 1 NA NA NA NA
#> 2 NA NA NA NA
#> 3 NA NA NA NA
#> 4 2 2 NA NA
#> 5 3 3 2 2
#> 6 4 4 3 3
#> 7 5 5 4 4
#> 8 6 6 5 5
#> 9 7 7 6 6
#> 10 8 8 7 7
#> 11 9 9 NA NA
#> 12 10 10 NA NA
#> 13 NA NA NA NA
#> 14 NA NA NA NA