【问题标题】:Replacing NA found with filter() using lapply() when all df do not have NA [duplicate]当所有 df 都没有 NA 时,使用 lapply() 用 filter() 替换找到的 NA [重复]
【发布时间】:2018-12-22 03:42:37
【问题描述】:

我在尝试通过调用 filter() 来替换数据帧中的 NA 时遇到了麻烦。

tib <- as_tibble(data.frame("Group"= c("A", "A", "A", "A", "A", "A", "B", "B", "B", "B", "B", "B"), "Color" = c("Red", "Red", "Red", "Blue", "Blue", "Blue", "Red", "Red", "Red", "Blue", "Blue", "Blue"), "Value" = c(5,NA,6,NA,16,12,4,5,6,10,12,17)))

> list.tib <- split(tib, tib$Group)
> list.tib
$`A`
# A tibble: 6 x 3
  Group Color Value
  <fct> <fct> <dbl>
1 A     Red       5
2 A     Red      NA
3 A     Red       6
4 A     Blue     NA
5 A     Blue     16
6 A     Blue     12

$B
# A tibble: 2 x 3
  Group Color Value
  <fct> <fct> <dbl>
1 B     Red       4
2 B     Blue     17

我想使用 lapply 将 [["A"]] 中的 NA 替换为另一个值。

如果我尝试使用“

> lapply(list.tib, function(x) filter(x, is.na(Value))$Value <- 50)
Error in filter(x, is.na(Value))$Value <- 50 : 
  could not find function "filter<-"

我尝试了另一种方法,使用不同的格式来指定我想要的值,但最终出现了不同类型的错误。

> lapply(list.tib, function(x) x[which(is.na(x$Value)),]$Value <- 50)
Error in `$<-.data.frame`(`*tmp*`, "Value", value = 50) : 
  replacement has 1 row, data has 0

我认为这会引发错误,因为 [["B"]] 没有任何 NA,我正在尝试将 numeric(0) 设置为 50。

我想要一个可以提供以下输出的函数:

> list.tib
$`A`
# A tibble: 6 x 3
  Group Color Value
  <fct> <fct> <dbl>
1 A     Red       5
2 A     Red      50
3 A     Red       6
4 A     Blue     50
5 A     Blue     16
6 A     Blue     12

$B
# A tibble: 2 x 3
  Group Color Value
  <fct> <fct> <dbl>
1 B     Red       4
2 B     Blue     17

如果我执行以下操作,我就能得到这个期望的结果:

list.tib$A[which(is.na(list.tib$A$Value)),]$Value <- 50

但这不是一概而论的。我认为 lapply() 是对这项工作的要求,但我无法让它为观察的特定变量赋值。

感谢您的帮助!

【问题讨论】:

    标签: r dataframe dplyr tidyverse


    【解决方案1】:

    如果存在Value 列是所有data.frames,那么您可以简单地将lapply 写为:

    lapply(split(tib, tib$Group), function(x){
                    x$Value[is.na(x$Value)]<-50
                    x
                    })
    
    # $A
    # # A tibble: 6 x 3
    # Group  Color  Value
    # <fctr> <fctr> <dbl>
    # 1 A      Red     5.00
    # 2 A      Red    50.0 
    # 3 A      Red     6.00
    # 4 A      Blue   50.0 
    # 5 A      Blue   16.0 
    # 6 A      Blue   12.0 
    # 
    # $B
    # # A tibble: 6 x 3
    # Group  Color  Value
    # <fctr> <fctr> <dbl>
    # 1 B      Red     4.00
    # 2 B      Red     5.00
    # 3 B      Red     6.00
    # 4 B      Blue   10.0 
    # 5 B      Blue   12.0 
    # 6 B      Blue   17.0 
    

    【讨论】:

    • 代码第三行最后一个 x 的目的是什么?我知道前两行会显示 is.na() = TRUE 的“Value”内容,但我认为当您为 [["B"]]s numeric( 0)。不知何故,最后的 x 解决了这个问题。很抱歉,这是一个基本问题,我会在此期间阅读一些书以尝试学习。
    • 最终x 是为了确保您返回数据框本身。否则,它将根据 R 的规则仅返回 Value 列以返回最后一行的结果。
    【解决方案2】:

    我们可以使用mutateifelse

    library(tidyverse)
    
    lapply(list.tib, function(x) x %>% mutate(Value = ifelse(is.na(Value), 50, Value)))
    

    replace_na 来自tidyr

    lapply(list.tib, function(x) x %>% replace_na(list(Value = 50)))
    
    lapply(list.tib, function(x) x %>% mutate(Value = replace_na(Value, 50)))
    

    【讨论】:

    • 我认为这个答案很好,因为 ifelse() 的使用允许使用更通用的值来替换我在问题中寻找的 NA。
    猜你喜欢
    • 1970-01-01
    • 2019-06-10
    • 2016-05-10
    • 1970-01-01
    • 2019-11-05
    • 2014-11-30
    • 1970-01-01
    • 1970-01-01
    • 2016-01-09
    相关资源
    最近更新 更多