Примечание этот ответ начался как попытка решить гораздо более простую проблему, опубликованную в Как заменить все значения во фрейме данных вектором значений? .К сожалению, этот вопрос был закрыт как дубликат реального вопроса.Итак, я постараюсь предложить решение, основанное на замене уровней факторов для обоих случаев, здесь.
В случае, если существует только вектор (или один столбец фрейма данных), значения которого необходимо заменить и нет никаких возражений против использования коэффициента, который мы можем заставить вектор анализировать и изменять уровни фактора по мере необходимости:
x <- c(1, 1, 4, 4, 5, 5, 1, 1, 2)
x <- factor(x)
x
#[1] 1 1 4 4 5 5 1 1 2
#Levels: 1 2 4 5
replacement_vec <- c("A", "T", "C", "G")
levels(x) <- replacement_vec
x
#[1] A A C C G G A A T
#Levels: A T C G
Используя пакет forcats
, это можно сделать водна строка:
x <- c(1, 1, 4, 4, 5, 5, 1, 1, 2)
forcats::lvls_revalue(factor(x), replacement_vec)
#[1] A A C C G G A A T
#Levels: A T C G
В случае, если все значения нескольких столбцов фрейма данных необходимо заменить, подход может быть расширен.
foo <- data.frame(snp1 = c("AA", "AG", "AA", "AA"),
snp2 = c("AA", "AT", "AG", "AA"),
snp3 = c(NA, "GG", "GG", "GC"),
stringsAsFactors=FALSE)
level_vec <- c("AA", "AC", "AG", "AT", "GC", "GG")
replacement_vec <- c("0101", "0102", "0103", "0104", "0302", "0303")
foo[] <- lapply(foo, function(x) forcats::lvls_revalue(factor(x, levels = level_vec),
replacement_vec))
foo
# snp1 snp2 snp3
#1 0101 0101 <NA>
#2 0103 0104 0303
#3 0101 0103 0303
#4 0101 0101 0302
Обратите внимание, что level_vec
и replacement_vec
должны иметь одинаковую длину.
Что более важно, level_vec
должно быть complete , т. Е. Включать все возможные значения в соответствующих столбцах исходного фрейма данных.(Используйте unique(sort(unlist(foo)))
для подтверждения).В противном случае любые пропущенные значения будут приведены к <NA>
.Обратите внимание, что это также является требованием для ответа Мартина Морганса .
Так что, если нужно заменить только несколько различных значений, вам, вероятно, будет лучше с одним из других ответов,например, Рамната .