2017-02-28 69 views
0

我正在嘗試向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編碼。在這個例子中,艾米和凱蒂都拿到了BLT Flags,因爲他們的產品包含了BLT的所有成分,而John則缺少「生菜」。我很難創建一個循環來創建這個標誌。任何建議,非常感謝!

+0

重現的例子將不勝感激。 http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example – snoram

+1

我錯誤地輸入了我之前的例子。我希望上面的表格更有意義。 – mrp

+0

是否可能出現重複行,或者如果某個特定名稱出現3次,那麼BLT = 1? – snoram

回答

1

使用註釋中的信息如果名稱出現三次,則顯示爲 ,BLT_Flag應該爲1,我們可以只計數每個名稱出現的次數,並測試它是否爲三次。
然後根據名稱爲每一行構建BLT_Flag。 順便說一句,我將你的數據存儲在一個名爲Supplies的數據框中。

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 

但是,正如@索托斯指出的,這個解決方案對於這個問題非常具體。更通用的解決方案是提供配料清單並測試是否所有配料都可用於每個名稱。可以與實現:

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 

一如以往,我們生成表示每個名稱是否所有的成分都存在一個表,然後用它來創建標誌。

+0

抱歉...在想什麼完全不同。我正在考慮培根,番茄,奶酪組合,但後來我又餓了:) – Sotos

+0

OP的要求是BLT,而不是BTC。你應該爲此提出一個新問題。 – G5W

+0

儘管如此,您的解決方案不足以解釋這一點。 – Sotos

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) 

生成名稱和配料所需recipee所有組合

desiredrecipe <- expand.grid(Inventory = c("Bacon", "Lettuce", "Tomato"), 
          Name = unique(dtf$Name), 
          stringsAsFactors = FALSE) 
numberofingredients <- length(unique(desiredrecipe$Inventory)) 

檢查和配料名稱的所有組合都存在於所需recipee

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