Преобразуйте каждый фактор в столбце в тот, который имеет вторую по величине частоту в R

#r #matrix

#r #матрица

Вопрос:

У меня есть следующая матрица с разными строками в каждом столбце. Минимальное количество разных строк в одном столбце равно 2, некоторые столбцы содержат до 20 разных строк, некоторые столбцы содержат только две разные строки. Я хотел бы преобразовать строки в столбцах с более чем 2 разными строками в строки, которые имеют вторую по величине частоту. Иметь в каждом столбце две разные строки. Всегда есть один фактор с самой высокой частотой, но если есть две строки с малой частотой с одинаковой частотой, я хочу, чтобы они преобразовали строку в любой из них, неважно, какой.

Мой пример матрицы:

 n.mat <- structure(c("M", "M", "M", "M", "M", "F", "Y", "Y", "M", "M", 
"Y", "Y", "Z", "F", "F", "F", "M", "M", "X", "Y", "Y", "F", "F", 
"F", "A", "A", "A", "A", "A", "A", "A", "B", "A", "A", "A", "A", 
"A", "B", "B", "B", "C", "D", "D", "D", "E", "E", "E", "E"), .Dim = c(8L, 
6L), .Dimnames = list(c("r1", "r2", "r3", "r4", "r5", "r6", "r7", 
"r8"), NULL))

  [,1] [,2] [,3] [,4] [,5] [,6]
r1 "M"  "M"  "M"  "A"  "A"  "C" 
r2 "M"  "M"  "M"  "A"  "A"  "D" 
r3 "M"  "Y"  "X"  "A"  "A"  "D" 
r4 "M"  "Y"  "Y"  "A"  "A"  "D" 
r5 "M"  "Z"  "Y"  "A"  "A"  "E" 
r6 "F"  "F"  "F"  "A"  "B"  "E" 
r7 "Y"  "F"  "F"  "A"  "B"  "E" 
r8 "Y"  "F"  "F"  "B"  "B"  "E" 
 

Желаемый результат:

 n.mat <- structure(c("M", "M", "M", "M", "M", "Y", "Y", "Y", "Y", "Y", 
"Y", "Y", "Y", "F", "F", "F", "Y", "Y", "Y", "Y", "Y", "F", "F", 
"F", "A", "A", "A", "A", "A", "A", "A", "B", "A", "A", "A", "A", 
"A", "B", "B", "B", "D", "D", "D", "D", "E", "E", "E", "E"), .Dim = c(8L, 
6L), .Dimnames = list(c("r1", "r2", "r3", "r4", "r5", "r6", "r7", 
"r8"), NULL))

  [,1] [,2] [,3] [,4] [,5] [,6]
r1 "M"  "Y"  "Y"  "A"  "A"  "D" 
r2 "M"  "Y"  "Y"  "A"  "A"  "D" 
r3 "M"  "Y"  "Y"  "A"  "A"  "D" 
r4 "M"  "Y"  "Y"  "A"  "A"  "D" 
r5 "M"  "Y"  "Y"  "A"  "A"  "E" 
r6 "Y"  "F"  "F"  "A"  "B"  "E" 
r7 "Y"  "F"  "F"  "A"  "B"  "E" 
r8 "Y"  "F"  "F"  "B"  "B"  "E"
 

До сих пор я упорядочивал каждый фактор в каждом столбце в порядке убывания. Мой код:

 apply(msa_protein.mat_2, 2, function(x) {
  sort <- sort(table(x), decreasing=TRUE)
}
 

Комментарии:

1. Что в случае, если есть два со второй по величине частотой? Например M , и Y в col2 и col3.

2. Тогда не имеет значения, в какой из них я хотел бы преобразовать свой фактор.

Ответ №1:

Вы можете использовать apply with table , sort it и заменить выворачивание того, что оно не самое настоящее, на второе по величине.

 apply(n.mat, 2, function(x) {
    tt <- sort(table(x), TRUE)
    if(length(tt) > 2) {x[x != names(tt)[1]] <- names(tt)[2]}
    x
})
#   [,1] [,2] [,3] [,4] [,5] [,6]
#r1 "M"  "M"  "M"  "A"  "A"  "D" 
#r2 "M"  "M"  "M"  "A"  "A"  "D" 
#r3 "M"  "M"  "M"  "A"  "A"  "D" 
#r4 "M"  "M"  "M"  "A"  "A"  "D" 
#r5 "M"  "M"  "M"  "A"  "A"  "E" 
#r6 "Y"  "F"  "F"  "A"  "B"  "E" 
#r7 "Y"  "F"  "F"  "A"  "B"  "E" 
#r8 "Y"  "F"  "F"  "B"  "B"  "E"