我目前正在尝试向R中的数据框添加一列,如果满足某些条件,则会在第三列中生成一个标记。看看下面我的示例数据集。
Name | Inventory | BLT_Flag
Amy Bacon 1
Amy lettuce 1
Amy Tomato 1
John Bacon 0
John Tomato 0
Katie Bacon 1
Katie Lettuce 1
Katie Tomato 1
基本上,我正在尝试为BLT_Flag编码。在这个例子中,Amy和Katie都获得了BLT Flags,因为他们的库存包含了BLT的所有成分,而John却缺少了#34;生菜。"我很难创建一个循环来创建这个标志。非常感谢任何建议!
答案 0 :(得分:1)
使用评论中的信息如果出现名称
三次,BLT_Flag应为1,我们可以算一下
每个名称出现的次数,如果是3,则进行测试
然后根据名称为每一行构建BLT_Flag。
顺便说一句,我将您的数据存储在名为Supplies
的data.frame中。
SupplyTable = table(Supplies$Name) == 3
SupplyTable
Amy John Katie
TRUE FALSE TRUE
BLT_Flag = as.numeric(SupplyTable[Supplies$Name])
BLT_Flag
[1] 1 1 1 0 0 1 1 1
然而,正如@Sotos指出的那样,这个解决方案非常特定于这个问题。更通用的解决方案是提供成分列表并测试是否所有成分都可用于每个名称。这可以通过以下方式实现:
IngredientList = c("Bacon", "Tomato", "Lettuce")
SupplyTable = sapply(unique(Supplies$Name),
function(x) sum(!is.na(match(IngredientList,
Supplies$Inventory[Supplies$Name == x]))) == length(IngredientList ))
SupplyTable
Amy John Katie
TRUE FALSE TRUE
AllIngredientsFlag = as.numeric(SupplyTable[Supplies$Name])
AllIngredientsFlag
[1] 1 1 1 0 0 1 1 1
和以前一样,我们生成一个表格,表明每个名字是否存在所有成分,然后用它来创建标志。
答案 1 :(得分:0)
创建数据
library(dplyr)
dtf <- read.table(text = "Name Inventory
Amy Bacon
Amy Lettuce
Amy Tomato
John Bacon
John Tomato
Katie Bacon
Katie Lettuce
Katie Tomato ", header = TRUE, stringsAsFactors = FALSE)
为所需的食谱生成名称和成分的所有组合
desiredrecipe <- expand.grid(Inventory = c("Bacon", "Lettuce", "Tomato"),
Name = unique(dtf$Name),
stringsAsFactors = FALSE)
numberofingredients <- length(unique(desiredrecipe$Inventory))
检查所需食谱中是否存在名称和成分的所有组合
dtf2 <- dtf %>%
# say that it's present in the list
mutate(present = 1) %>%
full_join(desiredrecipe, by = c("Name","Inventory")) %>%
group_by(Name) %>%
mutate(BLT_Flag = ifelse(sum(present)==numberofingredients,1,0))
# replace NA values by 0
dtf2$BLT_Flag[is.na(dtf2$BLT_Flag)] <- 0
dtf2
# Name Inventory present BLT_Flag
# <chr> <chr> <dbl> <dbl>
# 1 Amy Bacon 1 1
# 2 Amy Lettuce 1 1
# 3 Amy Tomato 1 1
# 4 John Bacon 1 0
# 5 John Tomato 1 0
# 6 Katie Bacon 1 1
# 7 Katie Lettuce 1 1
# 8 Katie Tomato 1 1
# 9 John Lettuce NA 0