【问题标题】:Filling in missing NA based upon factor level根据因子水平填写缺失的NA
【发布时间】:2022-01-01 02:22:52
【问题描述】:

我一直在尝试将我的数据从垂直配置转换为水平配置。使用spread(),我设法得到了以下结构:

plot, x1, x2, x3, x4, x5, x6, x7
1   0.06011071  NA  NA  NA  NA  NA  NA
1   NA  0.09756118  NA  NA  NA  NA  NA
1   NA  NA  NA  NA  0.143701    NA  NA
1   NA  NA  NA  NA  NA  0.1584451   NA
1   NA  NA  NA  0.1809486   NA  NA  NA
1   NA  NA  NA  NA  NA  NA  0.1151581
1   NA  NA  -0.1422974  NA  NA  NA  NA
7 rows

但是,显然我想用其他行的信息填写 NA。然后我的数据看起来像

plot , x1, x2, x3, x4, x5, x6, x7
1   0.06011071  0.09756118  -0.1422974NA    0.1809486   0.143701     0.1584451      0.1151581

我尝试了多种方法,但到目前为止都没有成功。有谁知道我如何做到这一点?

【问题讨论】:

  • 这个问题很可能可以通过调整你对“spread()”或“pivot_wider”的调用来预防

标签: r dataframe tidyr


【解决方案1】:

这样的?

df <- data.frame(x1 = c(1,NA,NA,NA,NA),
                 x2 = c(NA,2,NA,NA,NA),
                 x3 = c(NA,NA,3,NA,NA),
                 x4 = c(NA,NA,NA,4,NA),
                 x5 = c(NA,NA,NA,NA,5))
> df
  x1 x2 x3 x4 x5
1  1 NA NA NA NA
2 NA  2 NA NA NA
3 NA NA  3 NA NA
4 NA NA NA  4 NA
5 NA NA NA NA  5

for (i in 1:ncol(df)){
  df[,i][is.na(df[,i])] <- df[,i][!is.na(df[,i])]
}

> df
  x1 x2 x3 x4 x5
1  1  2  3  4  5
2  1  2  3  4  5
3  1  2  3  4  5
4  1  2  3  4  5
5  1  2  3  4  5

【讨论】:

  • OP 的预期输出只有一行。你有几个,所以我猜你很接近但不是 OP 想要的。
  • 虽然 OP 没有提供可重现的代码来创建示例数据框,但他或她确实提供了一个示例。我花了一些时间来创建可重现的代码来创建 OP 的示例。如果你愿意,你可以以我的例子作为你的答案。没有必要发明另一个可能不是 OP 需要的例子。
  • @www 是对的,我只想要一行输出。无论如何,感谢您抽出宝贵的时间,我对大家在这么短的时间内提供的帮助感到惊讶。
【解决方案2】:

这是使用dplyr 的解决方案。它假定您希望为每个 plot 保留从顶部开始的第一个非 NA 值。

library(dplyr)

dat2 <- dat %>%
  group_by(plot) %>%
  summarize(
    across(
      everything(),
      .fns = ~first(.x[!is.na(.x)])
    )
  ) %>%
  ungroup()
dat2
# # A tibble: 1 x 8
#    plot     x1     x2     x3    x4    x5    x6    x7
#   <int>  <dbl>  <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl>
# 1     1 0.0601 0.0976 -0.142 0.181 0.144 0.158 0.115

数据

dat <- read.table(text = "plot  x1  x2  x3  x4  x5  x6  x7
1   0.06011071  NA  NA  NA  NA  NA  NA
1   NA  0.09756118  NA  NA  NA  NA  NA
1   NA  NA  NA  NA  0.143701    NA  NA
1   NA  NA  NA  NA  NA  0.1584451   NA
1   NA  NA  NA  0.1809486   NA  NA  NA
1   NA  NA  NA  NA  NA  NA  0.1151581
1   NA  NA  -0.1422974  NA  NA  NA  NA",
                  header = TRUE)

【讨论】:

  • 谢谢,这正是我想要的。你上面的代码远远超出了我的熟练程度,但我会试着理解它。这是我第一次使用社区,对每个人提供的帮助感到非常惊讶。
  • @McPauwl 如果您对代码有疑问,可以告诉我。很高兴能提供帮助。
【解决方案3】:

或者:

library(tidyverse)

d <- read.table(text = "plot, x1, x2, x3, x4, x5, x6, x7
1   0.06011071  NA  NA  NA  NA  NA  NA
1   NA  0.09756118  NA  NA  NA  NA  NA
1   NA  NA  NA  NA  0.143701    NA  NA
1   NA  NA  NA  NA  NA  0.1584451   NA
1   NA  NA  NA  0.1809486   NA  NA  NA
1   NA  NA  NA  NA  NA  NA  0.1151581
1   NA  NA  -0.1422974  NA  NA  NA  NA", header = TRUE)

d %>%
  summarise(across(starts_with("x"), sum, na.rm = TRUE))

#x1.        x2.        x3.       x4.      x5.       x6.        x7
#1 0.06011071 0.09756118 -0.1422974 0.1809486 0.143701 0.1584451 0.1151581

【讨论】:

    【解决方案4】:

    我们也可以将na.omit 与 dplyr 一起使用:

    df %>% group_by(plot) %>% summarise(across(matches('x\\d+'), na.omit))
    

    【讨论】:

      【解决方案5】:

      也许:

      library(tidyverse)
      
      df <- read.table(text = "plot, x1, x2, x3, x4, x5, x6, x7
      1   0.06011071  NA  NA  NA  NA  NA  NA
      1   NA  0.09756118  NA  NA  NA  NA  NA
      1   NA  NA  NA  NA  0.143701    NA  NA
      1   NA  NA  NA  NA  NA  0.1584451   NA
      1   NA  NA  NA  0.1809486   NA  NA  NA
      1   NA  NA  NA  NA  NA  NA  0.1151581
      1   NA  NA  -0.1422974  NA  NA  NA  NA", header = TRUE)
      
      
      #if every column has only one value and the rest are NA's
      
      tibble(plot = 1, map_dfc(df[, -1], ~.[!is.na(.)]))
      #> # A tibble: 1 × 8
      #>    plot    x1.    x2.    x3.   x4.   x5.   x6.    x7
      #>   <dbl>  <dbl>  <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl>
      #> 1     1 0.0601 0.0976 -0.142 0.181 0.144 0.158 0.115
      
      #or gathering and spreading approach
      
      pivot_longer(df,cols = matches('^x\\d'), names_to = 'x') %>% 
        filter(!is.na(value)) %>% 
        arrange(x) %>% 
        pivot_wider(names_from = 'x', values_from = 'value')
      #> # A tibble: 1 × 8
      #>   plot.    x1.    x2.    x3.   x4.   x5.   x6.    x7
      #>   <int>  <dbl>  <dbl>  <dbl> <dbl> <dbl> <dbl> <dbl>
      #> 1     1 0.0601 0.0976 -0.142 0.181 0.144 0.158 0.115
      

      reprex package (v2.0.1) 于 2021 年 11 月 22 日创建

      【讨论】:

        猜你喜欢
        • 2015-01-27
        • 2017-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-28
        • 2014-03-21
        相关资源
        最近更新 更多