【问题标题】:Replace NA values with 999 in R subsetted by ID用 ID 子集的 R 中的 999 替换 NA 值
【发布时间】:2019-02-28 07:16:52
【问题描述】:

我在 R 中创建了以下数据框

    df<-data.frame("ID"=c("A", "A", "A", "B", "B", "B"),"II"=c(NA, NA, 
    NA,1,2,3),"JJ"=c(1,2,3, NA, NA, NA), 'KK'=c(1,2,NA, NA, 5,6))

生成的dataframe如下

  ID II JJ KK
   A NA  1  1
   A NA  2  2
   A NA  3 NA
   B  1 NA NA
   B  2 NA  5
   B  3 NA  6

我想通过 ID 值对数据框进行子集化,并将所有仅包含 NA 值的列替换为 999。结果应如下所示

 ID  II  JJ KK
  A 999   1  1
  A 999   2  2
  A 999   3 NA
  B   1 999 NA
  B   2 999  5
  B   3 999  6

我试过这个代码

   library(dplyr)
   df%>%
   group_by(ID)%>%
   select(II, JJ,KK)%>%
   mutate_if(df[, colSums(is.na(df)) == nrow(df)]<999)

我收到以下错误

 Adding missing grouping variables: `ID`
 Error in tbl_if_vars(.tbl, .p, .env, ..., .include_group_vars = 
 .include_group_vars) : 
 length(.p) == length(tibble_vars) is not TRUE

我请人看一看。我无法弄清楚。对于基于 dplyr 的解决方案不是必需的

【问题讨论】:

  • 不是@tifu推荐的副本
  • 你是对的,将删除推荐

标签: r dplyr subset


【解决方案1】:

我们可以使用all 来捕获具有所有 NA 的组。既然我们想替换所有列中的NAs,那么我们可以使用mutate_all,其中funs(即要应用于所有列的函数)是@987654326 所在组的简单replace() @ 值是 NA。替换为999

library(tidyverse)

df %>% 
 group_by(ID) %>% 
 mutate_all(funs(replace(., all(is.na(.)), 999)))

给出,

# A tibble: 6 x 4
# Groups:   ID [2]
  ID       II    JJ    KK
  <fct> <dbl> <dbl> <dbl>
1 A       999     1     1
2 A       999     2     2
3 A       999     3    NA
4 B         1   999    NA
5 B         2   999     5
6 B         3   999     6

【讨论】:

  • 整洁。请问楼主是怎么操作的。我很清楚 group_by 但从 mutate_all 我有点不清楚
  • @marciaakshayaLeo 我添加了一个解释。如果您有任何其他问题,请告诉我
【解决方案2】:

也加入data.table 解决方案:

library(data.table)
setDT(df)
df[, lapply(.SD, 
            function(col) if (all(is.na(col))) 999 else col), 
     by = ID]
#    ID  II  JJ KK
# 1:  A 999   1  1
# 2:  A 999   2  2
# 3:  A 999   3 NA
# 4:  B   1 999 NA
# 5:  B   2 999  5
# 6:  B   3 999  6

我们用lapply遍历所有非ID列,如果所有列都是NA,则用999替换它们。

【讨论】:

  • 您可以使用setDT() 而不是as.data.table()(这样更快)并且您不需要指定.SDcols --- 它自动是by 中未指定的所有列.
  • 谢谢,我只是在学习data.table(我更像是dplyr 家伙)- 将更改代码,感谢您的洞察力,非常有帮助! +1
【解决方案3】:

还有一个基本的 r 方法:

df[sapply(df, function(x)
  if(is.numeric(x)) is.na(ave(x, df$ID, FUN = function(y)
    mean(y, na.rm = TRUE))) else rep(FALSE, length(x)))] <- 999

df
  ID  II  JJ KK
1  A 999   1  1
2  A 999   2  2
3  A 999   3 NA
4  B   1 999 NA
5  B   2 999  5
6  B   3 999  6

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2020-04-09
    • 2019-10-11
    • 2012-03-08
    • 2016-03-08
    相关资源
    最近更新 更多