У меня есть данные, в которых каждая запись (строка) имеет уникальный id
.
В зависимости от первой буквы этого id
наблюдения можно разделить на две группы. Я хочу, чтобы столбец / переменная определяла группу.
Следующий код работает. Но мой вопрос в том, есть ли более элегантный R-способ сделать это?
> df <- data.frame(id = c("C-1", "P-2", "P-3", "C-2"))
> df$tmp_id <- startsWith(as.character(df$id), "C-")
> df
id tmp_id
1 C-1 TRUE
2 P-2 FALSE
3 P-3 FALSE
4 C-2 TRUE
> df$typ[df$tmp_id == TRUE] <- "C"
> df$typ[df$tmp_id == FALSE] <- "P"
> df$typ <- factor(df$typ, levels=c("C", "P"), labels=c("Cheese", "Pork"))
> df
id tmp_id typ
1 C-1 TRUE Cheese
2 P-2 FALSE Pork
3 P-3 FALSE Pork
4 C-2 TRUE Cheese
> df$tmp_id <- NULL
> df
id typ
1 C-1 Cheese
2 P-2 Pork
3 P-3 Pork
4 C-2 Cheese
И расширение моего вопроса: как бы я справился с этой ситуацией, если бы у меня было больше двух групп? е. грамм. Cheese
, Pork
, Candy
, Chocolate
Пакет dplyr
прекрасно справляется с этим. Я думаю, что вам нужно, если переменная / столбец flagging
или flag
. Это скажет вам, какие строки соответствуют определенному условию, а какие нет. Следующий код сгенерирует флаг с кодом 1
для всех строк, которые начинаются с C
в столбце id
. Столбец type
- это просто еще один флаг, и его можно создать таким же образом с помощью оператора ifelse
.
require(dplyr)
df <- data.frame(id = c("C-1", "P-2", "P-3", "C-2")) # OP's dataset
df %>%
mutate(flag = ifelse(str_detect(id,'C'),1,0), # mutate adds columns
type = ifelse(flag == 1,'Cheese','Pork'))
# A tibble: 4 x 3
id flag type
<chr> <dbl> <chr>
1 C- 1 1.00 Cheese
2 P- 2 0 Pork
3 P- 3 0 Pork
4 C- 4 1.00 Cheese
Простым подходом было бы создание именованного вектора, скажем types
, для использования в качестве
таблица поиска для привязки префиксов к группам. Затем вы можете извлечь
префикс из столбца id
и проиндексируйте вектор поиска, чтобы найти
соответствующее название группы:
df <- data.frame(id = c("C-1", "P-2", "P-3", "C-2"))
types <- c(C = "Cheese", P = "Pork")
df$typ <- types[substr(df$id, 1, 1)]
df
#> id typ
#> 1 C-1 Cheese
#> 2 P-2 Pork
#> 3 P-3 Pork
#> 4 C-2 Cheese
Если вы хотите добавить дополнительные группы, все, что вам нужно сделать, это добавить еще сопоставления префиксных групп с вектором, действующим как справочная таблица:
df <- data.frame(id = c("Ch-1", "Po-2", "Po-3", "Ca-2"))
types <- c(Ca = "Candy", Ch = "Cheese", Po = "Pork")
df$typ <- types[substr(df$id, 1, 2)]
df
#> id typ
#> 1 Ch-1 Cheese
#> 2 Po-2 Pork
#> 3 Po-3 Pork
#> 4 Ca-2 Candy
Если вы хотите разрешить префиксы различной длины, вы можете захотеть
взгляните на регулярные выражения для их извлечения из столбца id
.
Создано 02.05.2018 пользователем пакет REPEX (v0.2.0).
Но df$typ
- это character
, а не factor
. Вот бы просто добавить эту строчку df$typ <- factor(df$typ, levels=c("C", "P"), labels=c("Cheese", "Pork"))
или есть еще более элегантный способ? ;)
Я никогда не думал об именовании в c
, но если вы укажете для него имена аргументов, они будут использоваться для создания имен для результирующего вектора. Кажется, я не могу найти документацию по такому поведению. Что касается factor
, проще всего было бы просто использовать as.factor
: df$typ <- as.factor(types[substr(df$id, 1, 1)])
. Если вы не хотите, чтобы уровни факторов были в определенном порядке, в этом случае factor
, как вы предлагаете, будет подходящим вариантом.
Строка № 3 (
types
...) интересная! Я никогда не видел такого синтаксиса. Почему можно писатьCa
без кавычек? У вас есть ссылка на соответствующую базовую часть документа R?