Как мне отфильтровать данные во фрейме данных и изменить значения ячеек столбца на их основе с помощью al oop? - PullRequest
2 голосов
/ 30 мая 2020

В настоящее время работает с большим фреймом данных с различными идентификаторами участников, который выглядит следующим образом:

#ASC_new Data Frame

           Pcp Choice Target ASC       Product choice_consis
2393 zwyn27soc      B      A   1     USB drive             0
2394 zwyn27soc      B      A   1           job             0
2395 zwyn27soc      B      B   1     USB drive             0
2397 zwyn27soc      B      A   1       printer             0
2399 zwyn27soc      B      B   1 walking shoes             0
2400 zwyn27soc      B      A   1       printer             0

Я хотел бы попробовать l oop через каждого участника (Pcp) и посмотреть на их выбор в столбце «Выбор». Например, для обоих продуктов «USB-накопитель» участник выбрал «B» (выбор). Поэтому в разделе «selection_consis» я хочу, чтобы вместо 0 была 1, потому что варианты согласованы или равны. Хотя мой for l oop для просмотра участников и названий продуктов не работает:

#Examples/snippets of my values

pcp_list <- list("ybg606k3l", "yk83d2asc", "yl55v0zhm", "zwyn27soc")
product_list <- list("USB drive", "printer", "walking shoes", "job")

#for loop that isn't working
for (i in pcp_list){ #iterating through participant codes
  for (j in product_list){ #iterating through product names
    comparison <- filter(ASC_new, Pcp == i & Product == j) #filtering participant data and products into new dataframe

    choice_1 <- ASC_new$Choice[1] #creating labels for choice 1 and 2
    choice_2 <- ASC_new$Choice[2]

    if (isTRUE(choice_1 == choice_2)){ #comparing choice 1 and choice 2 and adding value of 1 to Choice_consis column if they are equal

      ASC_new$choice_consis[1] <- 1
      ASC_new$choice_consis[2] <- 1

    } 
  }

}

В конце я хотел бы получить фрейм данных, где selection_consis каждого участника помечен цифрами 1 или 0 выражая, выбрали ли они один и тот же элемент (A, B, D) оба раза, когда появлялся каждый продукт.

Ответы [ 2 ]

3 голосов
/ 30 мая 2020

Это то, что довольно естественно сделать, используя 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 *

Надеюсь, это поможет!

1 голос
/ 30 мая 2020

Вы можете подсчитать уникальное значение Choice для каждого Pcp и Product и присвоить 1, если оно равно 1, или 0 в противном случае.

Это можно сделать в базе R:

df$choice_consis <- +(with(df, ave(Choice, Pcp, Product, FUN = function(x)
                           length(unique(x)))) == 1)

dplyr:

library(dplyr)
df %>%
  group_by(Pcp, Product) %>%
  mutate(choice_consis = +(n_distinct(Choice) == 1))

и data.table

library(data.table)
setDT(df)[, choice_consis := as.integer(uniqueN(Choice) == 1), .(Pcp, Product)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...