Есть три простых метода.Вначале я собираюсь немного изменить данные (убрать «Другое»), чтобы выделить одну из сильных сторон одного из методов.
df <- data.frame(weather = c('Clear','Snow','Clear','Rain','Rain','Other','Hail/sleet','Unknown'))
weather.levels <- list(
dry = c('Clear', 'Cloudy'),
wet = c('Snow', 'Rain', 'Hail/sleet'),
other = c('Unknown'))
Простой поиск
levels1 <- c(Unknown="other",Snow="wet",Rain="wet","Hail/sleet"="wet",Clear="dry",Cloudy="dry")
### levels1 <- setNames(rep(names(weather.levels), lengths(weather.levels)), unlist(weather.levels))
transform(df, newwx = levels1[as.character(weather)])
# weather newwx
# 1 Clear dry
# 2 Snow wet
# 3 Clear dry
# 4 Rain wet
# 5 Rain wet
# 6 Other <NA>
# 7 Hail/sleet wet
# 8 Unknown other
(я использую transform
, который является base-R, но вы можете легко использовать dplyr
и такие, если вам удобнее.)
Объединение таблиц
По сути, это то, что делает ответ Шри (хотя концепция не только dplyr
и друзья).
df2 <- data.frame(wxfrom = names(levels1), wxto = levels1, stringsAsFactors=FALSE, row.names=NULL)
merge(df, df2, by.x="weather", by.y="wxfrom", all.x=TRUE)
# weather wxto
# 1 Clear dry
# 2 Clear dry
# 3 Hail/sleet wet
# 4 Other <NA>
# 5 Rain wet
# 6 Rain wet
# 7 Snow wet
# 8 Unknown other
Похоже на:
dplyr::left_join(df, df2, by=c("weather"="wxfrom"))
Lookup По умолчанию
transform(df, newwx = levels1[ match(as.character(weather), names(levels1), nomatch=1L) ])
# weather newwx
# 1 Clear dry
# 2 Snow wet
# 3 Clear dry
# 4 Rain wet
# 5 Rain wet
# 6 Other other
# 7 Hail/sleet wet
# 8 Unknown other
Этот последний обладает врожденной способностью назначать неизвестное любым несоответствиям.С остальными это так же просто, как сделать ifelse(is.na(newwx), "unk", newwx)
, так что это не добавляет много.