Это то, что довольно естественно сделать, используя dplyr
, если вас не волнует сворачивание различных вариантов. Я проиллюстрирую это на игрушечном фрейме данных:
IDs <- 1:2
choices <- c('A', 'B')
products <- c('USB', 'Printer')
df <- data.frame(Pcp = rep(IDs, each = 4),
Choice = c(rep(choices, each = 2),
rep(choices, each = 2)),
Product = c(rep(products, times = 2),
rep(products, each = 2)))
df %>%
dplyr::group_by(Pcp, Product) %>%
dplyr::summarize(choice_consis = as.numeric(length(unique(Choice)) == 1))
Это делает (по сути) то же самое, что вы пытаетесь сделать с вашим for l oop: посмотрите на каждую комбинацию участников и продуктов (это то, что делает group_by
), а затем проанализируйте эту комбинацию (это то, что делает summarize
). Это немного более лаконично и читабельно, чем двойное для l oop. Я бы посмотрел главу 5 книги Хэдли по R for Data Science , чтобы узнать больше о подобных вещах.
Что касается того, что не так с вашим для l oop, проблема в том, что даже если вы создаете свой фрейм данных comparison
, все последующие операции выполняются на ASC_new
. Итак, если вы хотите использовать для l oop и сохранить структуру ваших исходных данных, вы можете сделать что-то вроде:
for (i in pcp_list) {
for (j in product_list) {
compare <- (ASC_new$Pcp == i) & (ASC_new$Product == j)
choices <- ASC_new$Choice[compare]
if (length(unique(choices)) == 1) {
ASC_new$choice_consis[compare] <- 1
}
}
}
Создание нового фрейма данных, как вы это сделали, немного усложняет замените значения в оригинале (потому что мы не знаем «откуда» отфильтрованный фрейм данных), поэтому я просто получаю индексы исходного фрейма данных, соответствующие комбинации участник-продукт. Также обратите внимание, что я устранил жесткое кодирование того факта, что есть только два варианта, а также isTRUE
в операторе if (==
будет оценивать как TRUE
или FALSE
, по желанию) *. 1020 *
Надеюсь, это поможет!