当所有df没有NA时,使用lapply()替换使用filter()找到的NA

时间:2018-07-13 17:57:15

标签: r dataframe dplyr tidyverse

我一直很难尝试通过调用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替换为另一个值。

如果我尝试使用“ <-”或“ =”为NA分配一个任意值(此处使用50),则会出现错误,指出“找不到函数“ filter <-”

> 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

我想抛出一个错误是因为[[“”“”]没有任何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()是这项工作的要求,但我无法通过它为观察值的特定变量分配值。

谢谢您的帮助!

2 个答案:

答案 0 :(得分: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 

答案 1 :(得分:0)

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