R — проверить, существует ли элемент из вектора в data.frame, и если нет, добавить фиктивные значения

Имея вектор кампаний:

campaignsTypes <- c("Social Media","Distribution","Nurture","Newsletter","Push")

и data.frame с информацией о них:

out <- structure(list(Type = c("Distribution", "Newsletter", "Nurture", 
"Social Media"), Pageviews = c(42, 880, 17, 84)), .Names = c("Type", 
"Pageviews"), row.names = c(NA, -4L), class = "data.frame")

Я хочу проверить, включены ли все элементы из вектора campaignsTypes в data.frame out, и если нет, создать новую строку с фиктивными значениями для этой отсутствующей кампании. Пока что я могу проверить, отсутствует ли тип кампании. Однако у меня возникают проблемы с назначением несуществующего элемента из вектора в качестве значения для первого столбца новой строки, вставленной вручную:

> ifelse(campaignsTypes %in% out$Type == FALSE,rbind(out, c(????,0)),"")
How to put the value of the missing campaign here?----------⤴

person agustin    schedule 05.05.2016    source источник
comment
Каков ваш ожидаемый результат? Вам нужно campaignsTypes$ind <- if(all(campaignsTypes %in% out$Type)) 1 else 0   -  person akrun    schedule 05.05.2016
comment
@akrun, ожидаемый результат должен быть data.frame, например output <- structure(list(Type = c("Distribution", "Newsletter", "Nurture", "Social Media", "Push"), Pageviews = c(42, 880, 17, 84,0)), .Names = c("Type", "Pageviews"), row.names = c(NA, -5L), class = "data.frame"), где output$Type должен включать все элементы вектора campaignsType. Если тип был включен в результате того, что утверждение %in%out$Type == FALSE истинно, output$Pageviews для этого наблюдения будет присвоено значение 0.   -  person agustin    schedule 05.05.2016
comment
Я отредактировал вопрос, чтобы удалить первое выражение ifelse, так как это создает путаницу :)   -  person agustin    schedule 05.05.2016


Ответы (2)


Вы можете создать новый фрейм данных с отсутствующими строками, а затем сложить два фрейма данных.

rbind(out, data.frame(Type=setdiff(campaignsTypes, out$Type),
                      Pageviews=0L))

Результат:

          Type Pageviews
1 Distribution        42
2   Newsletter       880
3      Nurture        17
4 Social Media        84
5         Push         0
person Ernest A    schedule 05.05.2016

Один из способов сделать это,

output <- rbind(out, campaignsTypes[sapply(campaignsTypes, function(i) !(i %in% out$Type))])
output$Pageviews[output$Pageviews == output$Type] <- 0
output
#          Type Pageviews
#1 Distribution        42
#2   Newsletter       880
#3      Nurture        17
#4 Social Media        84
#5         Push         0
person Sotos    schedule 05.05.2016
comment
Это решение работает идеально. Однако я выбрал решение Ernest A в качестве ответа только потому, что процесс выполняется всего за один шаг. - person agustin; 05.05.2016
comment
Это нормально. В любом случае, это лучший ответ. Я совершенно забыл о setdiff, поэтому использовал цикл... - person Sotos; 05.05.2016