获得每行最频繁的值并说明联系

时间:2020-07-21 17:38:39

标签: r count recode

样本数据:

df <- data.frame("ID" = 1:6, 
                 "Group1" = c("A", NA, "C", NA, "E", "C"), 
                 "Group2" = c("E", "C", "C", NA, "E", "E"),
                 "Group3" = c("A", "A", NA, NA, "C", NA),
                 "Group4" = c(NA, "C", NA, "D", "C", NA),
                 "Group5" = c("A", "D", NA, NA, NA, NA))

在每一行中,我要计算每个值的数量并将最频繁出现的值存储在新变量New.Group中。如果是平局,则应选择该行中的第一个值。应用于示例的逻辑:

New.Group的行1取值为A,因为它是该行中最频繁的值,而忽略了NA

行2取值为C,因为它也是最常见的值。

第3行与第2行相同。

第4行采用值D,因为它是该行中唯一的值。

在第5行中,EC的计数都为2,但是选择了E是因为在行C之前遇到了它。

第6行与第5行类似,CE的计数都为1,但是选择C是因为在行中E之前遇到了它。 / p>

所需的输出:

  ID Group1 Group2 Group3 Group4 Group5 New.Group
1  1      A      E      A   <NA>      A         A
2  2   <NA>      C      A      C      D         C
3  3      C      C   <NA>   <NA>   <NA>         C
4  4   <NA>   <NA>   <NA>      D   <NA>         D
5  5      E      E      C      C   <NA>         E
6  6      C      E   <NA>   <NA>   <NA>         C

3 个答案:

答案 0 :(得分:6)

我认为这可以满足您的需求。对于每一行,它创建每个字母的频率表,并选择最大的频率,同时保留列的顺序以保持联系。然后,它返回该表中第一列的名称。

感谢Henrik提出改进建议。

df$New.Group <- apply(df[-1], 1, function(x) {
names(which.max(table(factor(x, unique(x)))))
})

df
#>   ID Group1 Group2 Group3 Group4 Group5 New.Group
#> 1  1      A      E      A   <NA>      A         A
#> 2  2   <NA>      C      A      C      D         C
#> 3  3      C      C   <NA>   <NA>   <NA>         C
#> 4  4   <NA>   <NA>   <NA>      D   <NA>         D
#> 5  5      E      E      C      C   <NA>         E
#> 6  6      C      E   <NA>   <NA>   <NA>         C

答案 1 :(得分:3)

使用dplyrvctrs的一个选项(利用location中的vec_count()参数,“按首次看到按键的位置排序”)可以是:

df %>%
 rowwise() %>%
 mutate(New.Group = na.omit(vec_count(c_across(starts_with("Group")), "location")) %>%
         slice_max(count, with_ties = FALSE) %>%
         pull(key))

     ID Group1 Group2 Group3 Group4 Group5 New.Group
  <int> <fct>  <fct>  <fct>  <fct>  <fct>  <fct>    
1     1 A      E      A      <NA>   A      A        
2     2 <NA>   C      A      C      D      C        
3     3 C      C      <NA>   <NA>   <NA>   C        
4     4 <NA>   <NA>   <NA>   D      <NA>   D        
5     5 E      E      C      C      <NA>   E        
6     6 C      E      <NA>   <NA>   <NA>   C 

或者:

df %>%
 rowwise() %>%
 mutate(New.Group = names(which.max(with(na.omit(vec_count(c_across(starts_with("Group")), "location")), setNames(count, key)))))

答案 2 :(得分:2)

我们可以使用Mode函数

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

df$New.Group <- apply(df[-1], 1, FUN = function(x) Mode(na.omit(x)))
df$New.Group
#[1] "A" "C" "C" "D" "E" "C"