簡體   English   中英

使用dplyr將列集中的NA替換為另一列集中的值

[英]Replace NA's in set of columns by values from another set of columns using dplyr

我發現了一些相關的問題,這些問題對某些問題有所幫助,但在關鍵方面各有不同,所以就到這里了。

我有一個帶有某些NA的數據框:

type <- LETTERS[1:5]
a_pc <- c(3, NA, NA , 4, 5)
b_pc <- c(NA, 2, 7, 4, 5)
a_pc_mean <- rep(mean(a_pc, na.rm = TRUE), times = 5)
b_pc_mean <- rep(mean(b_pc, na.rm = TRUE), times = 5)

df <- data.frame(type, a_pc, b_pc, a_pc_mean, b_pc_mean)

> df
  type a_pc b_pc a_pc_mean b_pc_mean
1    A    3   NA         4       4.5
2    B   NA    2         4       4.5
3    C   NA    7         4       4.5
4    D    4    4         4       4.5
5    E    5    5         4       4.5

我想將a_pcb_pc列中的NA替換為其相應的均值列中的值。 我認為一種干凈的方法是使用dplyr。 到目前為止,我的代碼是:

library(dplyr)

df2 <- df %>%
  mutate_at(.vars = vars(ends_with("_pc")),
            .funs = funs(replace(., is.na(.), ???)

我在問號所在的地方需要參考帶有方法的列,但是我無法弄清楚是什么。 我對dplyr的理解是. 引用vars(ends_with("_pc"))的列,所以我嘗試將paste0粘貼在一起. "_mean" ,但這沒有用。 這個問題很接近我的問題,但它要求用固定值代替,而不是花葯列中的值。

我的實際數據集有兩列以上要替換NA的列,因此我不希望明確引用它們。

編輯

我上面的原始問題並未說明我想做什么,因此為澄清起見,我發布了一個數據樣本:

 > crime_pop
   subregion                 iso    year assault kidnapping      pop assault_pc kidnapping_pc
   <fct>                     <chr> <dbl>   <dbl>      <dbl>    <dbl>      <dbl>         <dbl>
 1 Caribbean                 ABW    2008      NA         NA   101353 NA           NA         
 2 Southern Asia             AFG    2008      NA         NA 27294031 NA           NA         
 3 Middle Africa             AGO    2008      NA         NA 21759420 NA           NA         
 4 Southern Europe           ALB    2008     363         10  2947314  0.000123     0.00000339
 5 Southern Europe           AND    2008     105          0    83861  0.00125      0         
 6 Western Asia              ARE    2008     631        672  6894278  0.0000915    0.0000975 
 7 South America             ARG    2008  145240         NA 40382389  0.00360     NA         
 8 Western Asia              ARM    2008     201         27  2908220  0.0000691    0.00000928
 9 Caribbean                 ATG    2008      NA         NA    92478 NA           NA         
10 Australia and New Zealand AUS    2008   68019        611 21249200  0.00320      0.0000288 

我的想法是通過計算沒有丟失數據的國家的人均犯罪率,對這些國家的人均犯罪率進行插值,將其的次區域平均值求平均值,然后將其應用於具有丟失的數據。

要計算我使用的人均犯罪率:

crime_pop <- crime_pop %>%
  mutate_at(.vars = vars(assault:kidnapping),
            .funs = funs(pc = . / pop))

然后可以使用@Psidom的答案來計算子區域均值:

crime_pop2 <- crime_pop %>%
  group_by(year, subregion) %>%
  mutate_at(vars(ends_with("_pc")),
            funs(replace(., is.na(.), mean(., na.rm = TRUE))))

現在,NA處於assaultkidnapping需要分別用popassault_pc以及popkidnapping_pc assault_pc的乘積代替,這使我回到了原來的問題,即當在mutate_at使用時,在replace函數中引用其他列。 也許有一種更簡單的方法可以一次性完成所有這些工作,我願意提出建議。 謝謝!

只需使用mean(., na.rm=TRUE)作為替換:

df %>% mutate_at(vars(ends_with('_pc')), funs(replace(., is.na(.), mean(., na.rm=TRUE))))

#  type a_pc b_pc a_pc_mean b_pc_mean
#1    A    3  4.5         4       4.5
#2    B    4  2.0         4       4.5
#3    C    4  7.0         4       4.5
#4    D    4  4.0         4       4.5
#5    E    5  5.0         4       4.5

或者,您可以使用執行相同操作的coalesce ,即,如果來自中的值. 是NA,將其替換為均值:

df %>% mutate_at(vars(ends_with('_pc')), funs(coalesce(., mean(., na.rm=TRUE))))

#  type a_pc b_pc a_pc_mean b_pc_mean
#1    A    3  4.5         4       4.5
#2    B    4  2.0         4       4.5
#3    C    4  7.0         4       4.5
#4    D    4  4.0         4       4.5
#5    E    5  5.0         4       4.5

這是一個使用'dplyr :: select'提取名稱變量並將其傳遞給'Hmisc'包中的'impute'的解決方案。

bar   <- df  %>% dplyr::select(ends_with('_pc')) %>% 
sapply(., Hmisc::impute,fun= mean) 
df[, colnames(bar)] <- bar
df
#  type a_pc b_pc a_pc_mean b_pc_mean
#1    A    3  4.5         4       4.5
#2    B    4  2.0         4       4.5
#3    C    4  7.0         4       4.5
#4    D    4  4.0         4       4.5
#5    E    5  5.0         4       4.5

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM