如何过滤数据帧中的数据并使用循环基于它更改列的单元格值?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何过滤数据帧中的数据并使用循环基于它更改列的单元格值?相关的知识,希望对你有一定的参考价值。

当前正在使用具有各种参与者ID的较大数据框,如下所示:

#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

我想尝试遍历每个参与者(Pcp),并在“选择”列中查看他们的选择。例如,在两个产品“ USB驱动器”下,参与者都选择了“ B”(选择)。因此,在“ choice_consis”下,我希望将1替换为0,因为选择是一致的还是相等的。虽然,我无法遍历参与者和产品名称的for循环:

#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

     
  


最后,我想要一个数据框,其中每个参与者的choice_consis都用1或0标记,表示他们在每次出现两次产品时都选择相同的项目(A,B,D)。

答案

如果您不关心折叠在不同的选择上,那么使用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循环所做的相同:查看参与者和产品的每种组合(这是group_by所做的事情,然后分析该组合(这就是summarize ])。它比double for循环更简洁易读。我会查看Hadley's book on R for Data Science的第5章,以了解有关这些事情的更多信息。

就您的for循环出了什么问题,问题是,即使您创建了comparison数据帧,所有后续操作都在ASC_new上。因此,如果您想使用for循环并维护原始数据的结构,则可以执行以下操作:

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
     
  

像您一样创建一个新的数据框会使替换原始值中的值变得更加困难(因为我们不知道过滤后的数据框的“来源”),所以我只获取原始数据框的索引对应于参与者-产品组合。还要注意,我消除了硬编码这一事实,即只有两个选择,以及if语句中的isTRUE(根据需要==的计算结果为TRUEFALSE)。 >

希望这会有所帮助!

另一答案

您可以为ChoicePcp分别计算Product的唯一值,如果为1,则分配为1,否则为0。

以上是关于如何过滤数据帧中的数据并使用循环基于它更改列的单元格值?的主要内容,如果未能解决你的问题,请参考以下文章

基于将另一个单元格与另一个数据帧的单元格-熊猫进行比较,更改一个数据帧中单元格的值

根据 CSV 记录从 Spark 数据帧中过滤一些数据

在具有循环或 lambda 的多个数据帧中添加具有相同字符串值的列的更有效方法?

如果 pyspark 数据帧的行基于两列的值位于另一个数据帧中,如何删除它们?

如何使用过滤的数据框更新现有 Excel 工作表的一部分?

如何根据 Spark Scala 中其他数据帧中的多列匹配过滤数据帧