使用lapply填充数据帧中的NA值

时间:2020-01-14 19:16:38

标签: lapply

我想用NA值所在列中非NA值的平均值填充数据帧中的NA值。例如,在下面的数据帧ab中,我要用(5 + 6 + 7)/ 3 = 6替换b列中的所有NA,因为那是b列中所有非NA值的平均值。我想对所有其他列执行相同的操作。

ab<-data.frame(a=c(1,2,3,4),b=c(NA,5,6,7),c=c(4,NA,5,6),d=c(3,NA,NA,5))

  a  b  c  d
1 1 NA  4  3
2 2  5 NA NA
3 3  6  5 NA
4 4  7  6  5

我写下面的代码来做到这一点。

lapply(ab,function(b){lapply(b,function(c){c=ifelse (is.na(c)==TRUE,mean(b,na.rm=TRUE),c)})})

结果是

$a
$a[[1]]
[1] 1

$a[[2]]
[1] 2

$a[[3]]
[1] 3

$a[[4]]
[1] 4


$b
$b[[1]]
[1] 6

$b[[2]]
[1] 5

$b[[3]]
[1] 6

$b[[4]]
[1] 7


$c
$c[[1]]
[1] 4

$c[[2]]
[1] 5

$c[[3]]
[1] 5

$c[[4]]
[1] 6


$d
$d[[1]]
[1] 3

$d[[2]]
[1] 4

$d[[3]]
[1] 4

$d[[4]]
[1] 5

代替

  a  b  c  d
1 1  6  4  3
2 2  5  5  4
3 3  6  5  4
4 4  7  6  5

如果我这样做

as.data.frame(lapply(ab,function(b){lapply(b,function(c){c=ifelse (is.na(c)==TRUE,mean(b,na.rm=TRUE),c)})})) 

希望将lapply的结果转换为数据帧,我得到

  a.1 a.2 a.3 a.4 b.6 b.5 b.6.1 b.7 c.4 c.5 c.5.1 c.6 d.3 d.4 d.4.1 d.5
1   1   2   3   4   6   5     6   7   4   5     5   6   3   4     4   5

这是什么意思? 如何获得理想的结果?我确实看到R输出是表示期望结果的另一种方式,但我希望输出的数据帧具有预期的常规外观。

4 个答案:

答案 0 :(得分:1)

使用 na.aggregate 中的 zoo

library(zoo)
library(dplyr)
ab %>% 
     mutate(across(everything(), na.aggregate))

-输出

  a b c d
1 1 6 4 3
2 2 5 5 4
3 3 6 5 4
4 4 7 6 5

此外,默认情况下 na.aggregate 会用那些对应列的 mean 按列替换 NA。所以,它可以更紧凑

na.aggregate(ab)
  a b c d
1 1 6 4 3
2 2 5 5 4
3 3 6 5 4
4 4 7 6 5

答案 1 :(得分:1)

您也可以使用 map_if 包中的 purrr 函数:

library(dplyr)
library(purrr)

ab %>%
  map_if(~ any(is.na(.x)), ~ replace(.x, is.na(.x), mean(.x, na.rm = TRUE))) %>%
  bind_cols()

# A tibble: 4 x 4
      a     b     c     d
  <dbl> <dbl> <dbl> <dbl>
1     1     6     4     3
2     2     5     5     4
3     3     6     5     4
4     4     7     6     5

我们也可以将 replace 替换为 coalesce

ab %>%
  map_if(~ any(is.na(.x)), ~ coalesce(.x, mean(.x, na.rm = TRUE))) %>%
  bind_cols()

答案 2 :(得分:0)

k<-sapply(ab,function(b){lapply(b,function(c){c=ifelse(is.na(c)==TRUE,mean(b,na.rm=TRUE),c)})})
ans<-as.data.frame(k,nrow=4,ncol=4)

给予

  a b c d
1 1 6 4 3
2 2 5 5 4
3 3 6 5 4
4 4 7 6 5

答案 3 :(得分:0)

您可以使用 public final class UtilsKeyboard { /** * Sets the cursor at the end of this edit text and shows a keyboard */ public static void focusKeyboard(@NonNull EditText editText) { editText.requestFocus(); editText.setSelection(editText.getText().length()); showKeyboard(editText); } private static void showKeyboard(@NonNull View view) { final InputMethodManager manager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (manager != null) { manager.showSoftInput(view, InputMethodManager.SHOW_FORCED); } } public static boolean hideKeyboard(@NonNull Window window) { View view = window.getCurrentFocus(); return hideKeyboard(window, view); } private static boolean hideKeyboard(@NonNull Window window, @Nullable View view) { if (view == null) { return false; } InputMethodManager inputMethodManager = (InputMethodManager) window.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (inputMethodManager != null) { return inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); } return false; } public static boolean hideKeyboard(@Nullable View view) { if (view == null) { return false; } InputMethodManager inputMethodManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); if (inputMethodManager != null) { return inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); } return false; } /** * This will hide the keyboard and unfocus any focused view. */ public static void unfocusKeyboard(@NonNull Window window) { // When showing the bottom menu, make sure the keyboard isn't and that no view has focus hideKeyboard(window); final View focused = window.getCurrentFocus(); if (focused != null) focused.clearFocus(); }} -

lapply

或者用 ab[] <- lapply(ab, function(x) replace(x, is.na(x), mean(x, na.rm = TRUE))) # a b c d #1 1 6 4 3 #2 2 5 5 4 #3 3 6 5 4 #4 4 7 6 5 -

dplyr