Распределить объединенную переменную через запятую и двоеточие в отдельные логические столбцы - PullRequest
2 голосов
/ 02 апреля 2019

У меня есть df с одним столбцом feature_service, который содержит одну или несколько пар функций ( a - d ) со службами ( A или B ). функции и сервисы разделяются с помощью :, а пары разделяются usign ,.

df выглядит так:

df <- data.frame(feature_service = c("a:A", "a:A, b:A", "a:A, a:B", "a:B, b:B, c:B", "d:A, d:B"), stringsAsFactors = FALSE)
df
  feature_service
1             a:A
2        a:A, b:A
3        a:A, a:B
4   a:B, b:B, c:B
5        d:A, d:B

Теперь я хочу разделить службы и функции в отдельные логические столбцы. Цель - получить data.frame, который выглядит как :

df_goal <- data.frame(feature_a = c(TRUE, TRUE, TRUE, TRUE, FALSE), feature_b = c(FALSE, TRUE, FALSE, TRUE, FALSE), feature_c = c(FALSE, FALSE, FALSE, TRUE, FALSE)
                 , feature_d = c(FALSE, FALSE, FALSE, FALSE, TRUE), service_A = c(TRUE, TRUE, TRUE, FALSE, TRUE), service_B = c(FALSE, FALSE, TRUE, TRUE, TRUE))
df_goal
  feature_a feature_b feature_c feature_d service_A service_B
1      TRUE     FALSE     FALSE     FALSE      TRUE     FALSE
2      TRUE      TRUE     FALSE     FALSE      TRUE     FALSE
3      TRUE     FALSE     FALSE     FALSE      TRUE      TRUE
4      TRUE      TRUE      TRUE     FALSE     FALSE      TRUE
5     FALSE     FALSE     FALSE      TRUE      TRUE      TRUE

Как мне этого добиться?

Ответы [ 3 ]

3 голосов
/ 02 апреля 2019

Решение Base R:

foo <- strsplit(df$feature_service, ",")
# Get all possible features
feature <- unique(unlist(lapply(foo, function(x) trimws(sub(":.*", ":", x)))))
# Get all possible services
service <- unique(unlist(lapply(foo, function(x) trimws(sub(".*:", ":", x)))))

# Generate occurrence table
result <- sapply(c(feature, service), grepl, df$feature_service)
# Name final result
colnames(result) <- c(paste0("feature_", sub(":", "", feature)),
                      paste0("service_", sub(":", "", service)))

Если у вас уже есть все возможные функции и услуги, тогда необходима только часть sapply.

2 голосов
/ 02 апреля 2019

Один вариант с mtabulate после разделения столбца 'feature_service' на разделители

library(qdapTools)
out <- mtabulate(strsplit(df$feature_service, "[:, ]"))[-1] > 0

Или, используя tidyverse, создать столбец имен строк, разделить 'feature_service' с помощьюразделители в separate_rows, получают уникальные строки (distinct), создают логический столбец ИСТИНА и spread в «широкий» формат

library(tidyverse)
df %>% 
  rownames_to_column('rn') %>% 
  separate_rows(feature_service) %>%
  distinct(rn, feature_service) %>%
  mutate(n = TRUE) %>%
  spread(feature_service, n, fill = FALSE)

Если нам нужны имена столбцов, как указано,затем после разделения на ,, затем separate на два столбца ('key', 'val'), gather от 'wide' до 'long', unite столбец 'key / val'в один, и spread, как указано выше

df %>%
  rownames_to_column('rn') %>% 
  separate_rows(feature_service, sep = ", ") %>% 
  separate(feature_service, into = c('feature', 'service')) %>% 
  gather(key, val, feature:service) %>% 
  distinct() %>% 
  unite(keyval, key, val) %>% 
  mutate(n = TRUE) %>% 
  spread(keyval, n, fill =  FALSE) %>%
  select(-rn)
#  feature_a feature_b feature_c feature_d service_A service_B
#1      TRUE     FALSE     FALSE     FALSE      TRUE     FALSE
#2      TRUE      TRUE     FALSE     FALSE      TRUE     FALSE
#3      TRUE     FALSE     FALSE     FALSE      TRUE      TRUE
#4      TRUE      TRUE      TRUE     FALSE     FALSE      TRUE
#5     FALSE     FALSE     FALSE      TRUE      TRUE      TRUE
1 голос
/ 02 апреля 2019

Чтобы завершить трио (baseR, tidyverse, data.table), вот моя попытка с data.table,

library(data.table)
dt1 <- setDT(df)[, tstrsplit(feature_service, ", |:")]
dcast(melt(dt1, measure = names(dt1)), rowid(variable) ~ value, length)[,variable := NULL][] > 0

, что дает,

         A     B     a     b     c     d    NA
[1,]  TRUE FALSE  TRUE FALSE FALSE FALSE  TRUE
[2,]  TRUE FALSE  TRUE  TRUE FALSE FALSE  TRUE
[3,]  TRUE  TRUE  TRUE FALSE FALSE FALSE  TRUE
[4,] FALSE  TRUE  TRUE  TRUE  TRUE FALSE FALSE
[5,]  TRUE  TRUE FALSE FALSE FALSE  TRUE  TRUE

ПРИМЕЧАНИЕ: Он также дублирует NA, следовательно, дополнительный столбец в конце.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...