У меня есть длинная таблица с идентификатором, полем и значением, которая имеет дубликаты на каждый идентификатор в столбце «Поле». См. Ссылку ниже:
Ссылка на цветное изображение
| 306428 | game.name | Game Name |
|-------- |----------------- |----------- |
| 306428 | game.year | 2018 |
| 306428 | game.minplayers | 2 |
| 306428 | game.maxplayers | 4 |
| 306428 | game.category | A |
| 306428 | game.category | B |
| 306428 | game.category | C |
| 306428 | game.category | D |
| 306428 | game.category | E |
| 306428 | game.mechanic | A |
| id | name | year | minplayers | maxplayers | category | category_count | mechanic | mechanic_count |
|--------|-----------|------|------------|------------|-----------|----------------|----------|----------------|
| 306428 | Game Name | 2018 | 2 | 4 | A|B|C|D|E | 5 | A | 1 |
В конце игры также необходимо создать флаги для выбранного количества «множественных» полей (например, categoryF_A , categoryF_B) использовать для моделирования потенциального влияния на популярность / рейтинг. Полагаю, что объединенное поле в конечном итоге будет удалено.
| categories | categories_count | cat_A | cat_B | ... | cat_X |
|------------|------------------|-------|-------|-----|-------|
| A|B|C|D|E | 5 | 1 | 1 | ... | 0 |
Я совершенно новичок, поэтому я уверен, что есть способ с меньшим количеством кода и потенциально более эффективный, но я концептуализировал, начиная со следующего (также см. обновление «Текущее решение»):
new2<-games_data %>% group_by(game.id,field) %>%
summarise(Count_=length(value), Values = paste0(value,collapse="|"))
| game.id | field | Count_ | Values |
|---------|-----------------|--------|-----------|
| 306428 | game.year | 1 | 2018 |
| 306428 | game.maxplayers | 1 | 4 |
| 306428 | game.minplayers | 1 | 2 |
| 306428 | game.category | 5 | A|B|C|D|E |
| 306428 | game.mechanic | 1 | A |
, а затем объединили их в game.id. Затем я удаляю счетчики для столбцов с максимальным счетом 1 (снова см. Обновление «Текущее решение»).
Есть какие-нибудь мысли о правильном подходе к этому систематически или о функциях, которые могут сделать это для меня? Я играл с dcast, но сдался.
См. Ниже уменьшенные примеры данных для двух игр:
twogames <- data.frame(
game.id = c("275539","275539","275539","275539","275539","275539","275539","275539","275539","275539","275539","275551","275551","275551","275551","275551","275551","275551","275551","275551","275551","275551","275551","275551")
,field = c("game.name","game.minplayers","game.maxplayers","game.categoryid","game.categoryid","game.categoryid","game.category","game.category","game.category","game.mechanicid","game.mechanic","game.name","game.minplayers","game.maxplayers","game.categoryid","game.categoryid","game.categoryid","game.category","game.category","game.category","game.mechanicid","game.mechanicid","game.mechanic","game.mechanic")
,value = c("Tower Beast Slayers: Catacombs Expansion","1","4","1042","1017","1010","Expansion for Base-game","Dice","Fantasy","2072","Dice Rolling","Sweet Treats!","1","4","1002","1041","1120","Card Game","Children's Game","Print & Play","2023","2004","Cooperative Game","Set Collection")
, stringsAsFactors = FALSE)
---- ТЕКУЩЕЕ РЕШЕНИЕ -----
Используя приведенные выше данные, я использую приведенный ниже код, чтобы получить приведенный ниже результат. Мысли ??
#Group by ID and Field and create Count and Concatenated Fields
twogames_sum <- twogames %>% group_by(game.id,field) %>% summarise(count=length(value),values=paste0(value, collapse = "|"))
##Create Counts and Values for all fields
counts <- twogames_sum %>% select(-values) %>% spread(key=field,value=count) %>% rename_at(vars(-game.id),~ paste0(.,"_count"))
values <- twogames_sum %>% select(-count) %>% spread(key=field,value=values)
##Merge Unique IDs, Counts, and Values to one table
main <- data.table(game.id = unique(twogames_sum$game.id))
main <- merge(main,counts, by = "game.id")
main <- merge(main,values, by = "game.id")
##Remove any columns that always have one value
remove <- colnames(main%>% select(ends_with("count")) %>% select_if(~all(. == 1)))
main<- main %>% select(!all_of(remove))
##Fields to Create Flags For
fields <- c("mechanic","category")
##ID List and Suffix for each Field
mechanic <- c("2072","2023","2004")
mechanic_names <- c("dice","coop","setc")
category <- c("1042","1017","1010","1002","1041","1120")
category_names <- c("exp","dice","fant","card","child","print")
##For each value in fields, loop through each identified value to create a flag
for (i in 1: length(fields)){
field <- sym(fields[i])
suffixlist <- eval(sym(paste0(fields[i],"_names")))
valuelist <- eval(field)
for(j in 1: length(valuelist)){
column <- paste0("game.",field,"F_",suffixlist[j])
fieldname <- sym(paste0("game.",field,"id"))
value <- valuelist[j]
#Use above 3 fields to add column
main <- main %>% mutate(!!column := str_count(!!fieldname,!!value))
}
}
Результат:
$ game.id <dbl> 275539, 275551
$ game.category_count <int> 3, 3
$ game.categoryid_count <int> 3, 3
$ game.mechanic_count <int> 1, 2
$ game.mechanicid_count <int> 1, 2
$ game.category <chr> "Expansion for Base-game|Dice|Fantasy", "Card Game|Children's Game|Print & Play"
$ game.categoryid <chr> "1042|1017|1010", "1002|1041|1120"
$ game.maxplayers <chr> "4", "4"
$ game.mechanic <chr> "Dice Rolling", "Cooperative Game|Set Collection"
$ game.mechanicid <chr> "2072", "2023|2004"
$ game.minplayers <chr> "1", "1"
$ game.name <chr> "Tower Beast Slayers: Catacombs Expansion", "Sweet Treats!"
$ game.mechanicF_dice <int> 1, 0
$ game.mechanicF_coop <int> 0, 1
$ game.mechanicF_setc <int> 0, 1
$ game.categoryF_exp <int> 1, 0
$ game.categoryF_dice <int> 1, 0
$ game.categoryF_fant <int> 1, 0
$ game.categoryF_card <int> 0, 1
$ game.categoryF_child <int> 0, 1
$ game.categoryF_print <int> 0, 1