样本数据:
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行中,E
和C
的计数都为2,但是选择了E
是因为在行C
之前遇到了它。
第6行与第5行类似,C
和E
的计数都为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
答案 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)
使用dplyr
和vctrs
的一个选项(利用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"