【问题标题】:Compare column values in R through if else to fill third column通过 if else 比较 R 中的列值以填充第三列
【发布时间】:2017-03-01 22:48:06
【问题描述】:

我目前正在尝试向 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 标志,因为他们的库存包括 BLT 的所有成分,而 John 缺少“生菜”。我很难创建一个循环来创建这个标志。任何建议都非常感谢!

【问题讨论】:

  • 可重复的示例将不胜感激。 stackoverflow.com/questions/5963269/…
  • 我之前的示例输入错误。我希望上表更有意义。
  • 是否可能出现重复行,或者如果某个名称出现 3 次则 BLT = 1 的情况?
  • 因此,不能重复(会有唯一标识符)。如果某个名称出现 3 次,则 BLT=1。

标签: r


【解决方案1】:

使用如果出现名称的 cmets 中的信息 三次,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

和以前一样,我们生成一个表,为每个名称指示是否所有成分都存在,然后使用它来创建标志。

【讨论】:

  • 对不起……我在想一些完全不同的东西。我在想培根、西红柿、奶酪的组合,但我又饿了:)
  • OP 的请求是针对 BLT,而不是 BTC。您应该为此提出一个新问题。
  • 尽管如此,您的解决方案还不够通用,无法说明这一点。
  • 冒号短划线右括号
  • @Sotos 你是对的。我已经概括了解决方案。
【解决方案2】:

创建数据

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多