比较R中的列值if if else以填充第三列

时间:2017-02-28 16:09:41

标签: r

我目前正在尝试向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;生菜。"我很难创建一个循环来创建这个标志。非常感谢任何建议!

2 个答案:

答案 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