По сути, речь идет об использовании битовых масок / двоичных столбцов и ориентированных на строки операций с таблицей / фреймом данных: во-первых, для создания логического вектора из комбинации выбранных столбцов, которые можно использовать для маскирования вектора символов, представляющего «что»столбцы помечены.Во-вторых, расширение строки - учитывая количество в одном столбце, создайте таблицу данных, содержащую исходные данные строки, реплицированные это число раз.
Для суммирования флагов используется побитовая маска с разбивкой по строкам, которая использует purrr:уменьшить для конкатенации флагов, представленных строк, я не могу найти краткий метод, чтобы сделать это в цепочке%>%, а не отдельный цикл for.Я подозреваю, что purrr :: map требуется, но я не могу получить его / правильный синтаксис.
Для раскрытия строки вложенный цикл имеет ужасающую производительность, и я не могу найти путь для dplyr / purrr в строку-произведите эту строку определенное количество раз в строке.Карта и другие функции должны были бы создавать и добавлять несколько строк, на которые, я думаю, карта не способна.
Следующий код производит требуемый вывод - но, кроме проблем с производительностью (особенно в отношении расширения строк)), Я хотел бы иметь возможность делать это как векторизованные операции.
library(tidyverse)
library(data.table)
dt <- data.table(C1=c(0,0,1,0,1,0),
C2=c(1,0,0,0,0,1),
C3=c(0,1,0,0,1,0),
C4=c(0,1,1,0,0,0),
C5=c(0,0,0,0,1,1),
N=c(5,2,6,8,1,3),
Spurious = '')
flags <- c("Scratching Head","Screaming",
"Breaking Keyboard","Coffee Break",
"Giving up")
# Summarise states
flagSummary <- function(dt){
interim <- dt %>%
dplyr::mutate_at(vars(C1:C5),.funs=as.logical) %>%
dplyr::mutate(States=c(""))
for(i in 1:nrow(interim)){
interim$States[i] <-
flags[as.logical(interim[i,1:5])] %>%
purrr::reduce(~ paste(.x, .y, sep = ","),.init="") %>%
stringr::str_replace("^[,]","") }
dplyr::select(interim,States,N) }
summary <- flagSummary(dt)
View(summary)
# Expand states
expandStates <- function(dt){
interim <- dt %>%
dplyr::mutate_at(vars(C1:C5), .funs=as.logical) %>%
dplyr::select_at(vars(C1:C5,N)) %>%
data.table::setnames(.,append(flags,"Count"))
expansion <- interim[0,1:5]
for(i in 1:nrow(interim)){
for(j in 1:interim$Count[i]){
expansion <- bind_rows(expansion, interim[i,1:5]) } }
expansion }
expansion <- expandStates(dt)
View(expansion)
Как уже говорилось, код дает ожидаемый результат.Я бы хотел увидеть то же самое, не прибегая к циклам for и не имея возможности объединить функции в исходные мутировать / выбирать.