2016-07-19 81 views
0

我有一個項目編號和庫存位置列表。項目可以出現在兩類廣告位置 - warehousepar位置。我想一列添加到我的數據表明,如果一個特定的項目數量曾經與倉庫位置相關聯。下面的示例數據:R dplyr - 根據其他行中的結果添加列

item_num <- c("Item - 1", "Item - 2", "Item - 3", "Item - 1", "Item - 3", 
      "Item - 2") 
locs <- c("warehouse", "par", "par", "par", "warehouse", "par") 
fake_data <- tibble(item_num, locs) 

fake_data 
# A tibble: 6 x 2 
    item_num  locs 
    <chr>  <chr> 
1 Item - 1 warehouse 
2 Item - 2  par 
3 Item - 3  par 
4 Item - 1  par 
5 Item - 3 warehouse 
6 Item - 2  par 

我想補充的,將是TRUE所有Item - 1Item - 3因爲對於這兩個在我的數據倉庫位置的列。對於Item - 2這將是錯誤的。類似這樣的:

item_num  locs wh_exists 
1 Item - 1 warehouse  TRUE 
2 Item - 2  par  FALSE 
3 Item - 3  par  TRUE 
4 Item - 1  par  TRUE 
5 Item - 3 warehouse  TRUE 
6 Item - 2  par  FALSE 

我的混亂的解決方案如下。

wh_locs <- fake_data %>% 
    filter(locs == "warehouse") 
fake_data$wh_exist <- fake_data$item_num %in% wh_locs$item_num 

fake_data 

# A tibble: 6 x 3 
    item_num  locs wh_exist 
    <chr>  <chr> <lgl> 
1 Item - 1 warehouse  TRUE 
2 Item - 2  par FALSE 
3 Item - 3  par  TRUE 
4 Item - 1  par  TRUE 
5 Item - 3 warehouse  TRUE 
6 Item - 2  par FALSE 

這工作,但在我看來,應該有使用mutategroup_by得到的答案,所以我可以把它全部在一個管道組函數一些聰明的辦法。

謝謝。

回答

3

我們可以通過data.table

使用 any==

fake_data %>% 
     group_by(item_num) %>% 
     mutate(wh_exists = any(locs == "warehouse")) 
#  item_num  locs wh_exists 
#  <chr>  <chr>  <lgl> 
#1 Item - 1 warehouse  TRUE 
#2 Item - 2  par  FALSE 
#3 Item - 3  par  TRUE 
#4 Item - 1  par  TRUE 
#5 Item - 3 warehouse  TRUE 
#6 Item - 2  par  FALSE 

的類似選項

library(data.table) 
setDT(fake_data)[, wh_exists := any(locs == "warehouse"), by = item_num] 
1

使用group_by%in%運營商檢查warehouselocs每個組內:

library(dplyr) 
fake_data %>% group_by(item_num) %>% mutate(wh_exists = 'warehouse' %in% locs) 

# Source: local data frame [6 x 3] 
# Groups: item_num [3] 
# 
# item_num  locs wh_exists 
#  <fctr> <fctr>  <lgl> 
# 1 Item - 1 warehouse  TRUE 
# 2 Item - 2  par  FALSE 
# 3 Item - 3  par  TRUE 
# 4 Item - 1  par  TRUE 
# 5 Item - 3 warehouse  TRUE 
# 6 Item - 2  par  FALSE