用组的频繁值替换值

时间:2018-03-06 23:37:30

标签: r dplyr

关于替换组中最常值的值,我有一个非常基本的问题。

这就是我的意思

df <- data.frame(x=c(12,12,5,13,13,5),y=c(10,22,22,22,10,22),gr=gl(2,3))
> df
   x  y gr
1 12 10  1
2 12 22  1
3  5 22  1
4 13 22  2
5 13 10  2
6  5 22  2

我们可以看到,gr1 x列的频繁值为12,频率值为5的频率较低,y列的频率为10。我想分别用x和y代替666777替换这些值。在我的实际数据中,频繁的x值总是相同的,但是频率较低的值可以改变,所以一般的解决方案会很好。 dplyr解决方案是首选,因为实际数据已经在管道中。

library(dplyr)
df%>%
group_by(gr)%>%
....

预期产出

> df
   x  y  gr
1 12  777  1
2 12  22   1
3 666 22   1
4 13  22   2
5 13  777  2
6 666 22   2

2 个答案:

答案 0 :(得分:2)

df2=df%>%
  group_by(gr)%>%
  mutate_all(
    funs(table(.)%>%
            which.max()%>%
             names()%>%
                as.numeric()
         )
    )

df%>%
  `is.na<-`(df2!=df)%>%
     replace_na(list(x=666,y=777))

    x   y gr
1  12 777  1
2  12  22  1
3 666  22  1
4  13  22  2
5  13 777  2
6 666  22  2

答案 1 :(得分:2)

我们也可以在map2之后使用nest执行此操作。创建一个函数来计算最频繁的值('模式')

library(tidyverse)
Mode <- function(x) {
  ux <- unique(x)
   ux[which.max(tabulate(match(x, ux)))]
}

nest变量'x','y'之后,循环遍历map2的变量,用相应的替换值替换不常见的值,即666,777

df %>% 
   nest(-gr) %>% 
   mutate(data = map(data, ~ .x %>% 
                               map2_df(., c(666, 777), ~ 
                                replace(.x, .x != Mode(.x), .y))) ) %>% 
   unnest
#   gr   x   y
#1  1  12 777
#2  1  12  22
#3  1 666  22
#4  2  13  22
#5  2  13 777
#6  2 666  22

或者使用data.table,它会更容易一些。在data.table对象(setDT(df))中按'gr'分组后,使用Map将相应列非频繁值替换为相应的感兴趣值(666,777)

library(data.table)
setDT(df)[, Map(function(x, y) replace(x, x!= Mode(x), y), .SD, c(666, 777)), gr]
#   gr   x   y
#1:  1  12 777
#2:  1  12  22
#3:  1 666  22
#4:  2  13  22
#5:  2  13 777
#6:  2 666  22
相关问题