2015-10-22 2 views
1

Мне интересно, есть ли какая-либо функция в R, которая похожа на функцию разреза, но работает на строки?R cut функция для строк

Код, над которым я работаю, - это присвоить данные, касающиеся состояний в США, категориальной переменной Region: существует 4 региона Северо-Восток, Средний Запад, Юг, Запад. Кадр данных, хранящий каждый из данных, сохраняет имя состояния в переменной «состояние» и в сокращенной форме: «Нью-Йорк» для Нью-Йорка или «MS» для Миссисипи, например. Переменная области должна быть добавлена ​​к кадру данных, который я делаю в настоящее время следующим образом (это для домашней работы, поэтому я хочу показать, что у меня уже есть решение, и я просто ищу потенциально лучшего):

create.region <- function(state) { 
northeast <- c("CT", "ME", "MA", "NH", "RI", "VT", "NJ", "NY", "PA") 
midwest <- c("IL", "IN", "MI", "OH", "WI", "IA", "KS", "MN", "MO", "NE", "ND", "SD") 
south <- c("DE", "DC", "FL", "GA", "MD", "NC", "SC", "VA", "WV", "AL", "KY", "TN", "MS", "AR", "LA", "OK", "TX") 
west <- c("AZ", "CO", "ID", "MT", "NV", "NM", "UT", "WY", "AK", "CA", "HI", "OR", "WA") 
region <- ifelse(state %in% northeast, "Northeast", 
      ifelse(state %in% midwest, "Midwest", 
      ifelse(state %in% south, "South", 
      ifelse(state %in% west, "West", NA)))) 
return(region) 
} 
birth_data <- within(birth_data, region <- create.region(state)) 

Я еще не знаю много о R, и я заинтересован в эффективности моего кода. В прошлом я обнаружил, что функция вырезания является более кратким и эффективным способом категоризации цифровых данных таким образом, но, по-видимому, она не работает с символьными векторами. Есть ли какая-либо функция, подобная разрезу, которая допускает правило назначения символов, а не только числовые?

ответ

2

Самый простой способ - сопоставить имена через вектор.

Во-первых, мы готовим карту:

all_states = c('northeast', 'midwest', 'south', 'west') 

states_for_region = function (region) { 
    states = get(region) 
    setNames(rep(region, length(states)), states) 
} 

states_map = unlist(lapply(all_states, states_for_region)) 

Мы могли бы также построили states_map вручную для каждого региона, а затем конкатенировать результаты. Но вышесказанное менее повторяемо.

Затем мы делаем фактическое отображение, которое теперь требует только одну строку.

region = states_map[state] 

Для повышения эффективности, это хорошая идея, чтобы подготовить карту вне функции. В противном случае он будет восстанавливаться всякий раз, когда вы вызываете эту функцию.

2

Из коробки R включает переменные state.abb и state.region. Первый является символьным вектором всех сокращений состояний, а последний представляет собой коэффициент 4-го уровня той же длины, содержащий соответствующие регионы; Поэтому, чтобы получить область для MS, говорят:

state.region[state.abb == "MS"] 
## [1] South 
## Levels: Northeast South North Central West 

Если вы хотите другой категоризации было бы достаточно легко определить собственную альтернативу state.region, а затем использовать код выше.

В качестве примечания обратите внимание, что существует также state.name, длина которого равна указанной выше двум переменным и дает полное имя состояния.

0

Вы также можете использовать функцию levels<- вместе со своим списком сопоставлений.

Вот пример:

## Create your mapping.... 
## Overkill in this example as @Grothendieck has pointed out, 
## but still applicable in a general scenario 

myLevs <- list(
    Northeast = c("CT", "ME", "MA", "NH", "RI", "VT", "NJ", "NY", "PA"), 
    Midwest = c("IL", "IN", "MI", "OH", "WI", "IA", "KS", "MN", "MO", "NE", "ND", "SD"), 
    South = c("DE", "DC", "FL", "GA", "MD", "NC", "SC", "VA", "WV", "AL", "KY", "TN", "MS", "AR", "LA", "OK", "TX"), 
    West = c("AZ", "CO", "ID", "MT", "NV", "NM", "UT", "WY", "AK", "CA", "HI", "OR", "WA")) 

Теперь создать вектор образца:

set.seed(1) 
x <- sample(state.abb, 10) 

factor вектор, и изменить его levels.Это может быть сделано в два этапа (y <- factor(x); levels(y) <- myLevs) или в одну стадию с славная Загадочный ищет:

y <- `levels<-`(factor(x), myLevs) 

Вот результат:

x 
# [1] "IN" "ME" "NV" "TX" "GA" "SD" "TN" "NH" "NE" "AZ" 
y 
# [1] Midwest Northeast West  South  South  Midwest South  
# [8] Northeast Midwest West  
# Levels: Northeast Midwest South West 
Смежные вопросы