【问题标题】:R: In dataframe: set first non-NA value in column to NAR:在数据框中:将列中的第一个非 NA 值设置为 NA
【发布时间】:2017-10-23 23:58:37
【问题描述】:

我有一个大型数据框,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 中迈出第一步时,我完全忽略了一些事情。

我们将不胜感激所有建议!

【问题讨论】:

    标签: r dataframe na


    【解决方案1】:

    我们可以使用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))
    

    【讨论】:

    • 尽管我尽了最大的努力,但我还是想不出任何明显更快的东西。也许df[] &lt;- lapply(df, function(x) replace(x, Position(Negate(is.na), x), NA) ) 可能会很好,这意味着您可以增加一些开销并执行df[] &lt;- Map(replace, df, lapply(df, Position, f=Negate(is.na)), NA)
    【解决方案2】:

    由于您想对所有列执行此操作,您可以使用来自dplyrmutate_all 函数。请参阅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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多