2017-12-07 5 views
1

내가 큰 데이터 세트가 있지만 여기에 내가 동일한 데이터 논쟁 문제dplyr | group_by 대 anti_join | 가장 효율적인 방법

데이터가 샘플 데이터를 생성하고하는 것은

brand=c('MS', 'Google', 'Apple', 'MS', 'FB', 'Apple', 'Oracle') 
product=c('Window', 'Search', 'Iphone', 'Window', 'Network', 'Iphone', 'DB') 
isExist=c('Yes', 'Yes', NA, 'No', NA, 'Yes', NA) 
df= data.frame(brand, product, isExist) 

이 데이터는 지금이

brand product isExist 
1  MS Window  Yes 
2 Google Search  Yes 
3 Apple Iphone <NA> 
4  MS Window  No 
5  FB Network <NA> 
6 Apple Iphone  Yes 
7 Oracle  DB <NA> 

처럼 나는 isExist에 대한 NA 항목이없고 값이있는 동일한 복합 키에 대해 다른 행을 가지고 있지 않은 브랜드 및 제품 (복합 키)을 기반으로하는 행을 원합니다. 즉 FB, Oracle를 반환해야하지만 Apple은 행 중 하나가 아닙니다. ro 더 6) isExist 가치가 없다 승

I, 여기에 코드 anti_join을 사용하여 달성하고

library(dplyr) 
testWithData <- df %>% filter(!is.na(isExist)) 
testWithoutData <- df %>% filter(is.na(isExist)) 
final <- unique(anti_join(testWithoutData, testWithData, by = c('brand', 'product'))) 

출력

brand product isExist 
1  FB Network <NA> 
2 Oracle  DB <NA> 
이 솔루션은

을하고있다하지만 나는 알고있다, 너무 많은 시간이 소요 가장 효율적인 방법은 아닙니다. 나는 GROUP_BY 및 필터가 마법을 할 수 있다고 생각하지만, 나는 누군가가 먼저 (단계로이 단계를 실행하면 위의 과정을 이해할 수

+0

2 행, 먼저 3 등) NA의 (예 : 1). 내 질문에 대한 최상위 답변보기 : https://stackoverflow.com/questions/47289543/modify-certain-values-in-a-data-frame-by-indirect-reference-to-the-columns/47310247?noredirect= 1 # comment81573872_47310247 – Stanwood

답변

3
brand=c('MS', 'Google', 'Apple', 'MS', 'FB', 'Apple', 'Oracle') 
product=c('Window', 'Search', 'Iphone', 'Window', 'Network', 'Iphone', 'DB') 
isExist=c('Yes', 'Yes', NA, 'No', NA, 'Yes', NA) 
df= data.frame(brand, product, isExist) 

library(dplyr) 

df %>% 
    group_by(brand) %>%      # for each brand 
    filter(sum(!is.na(isExist)) == 0) %>% # get sum of values that are not NA and keep rows where the sum is 0 
    ungroup() 

# # A tibble: 2 x 3 
#  brand product isExist 
#  <fctr> <fctr> <fctr> 
# 1  FB Network <NA> 
# 2 Oracle  DB <NA> 

이 점에서 나를 도와주세요 수있는, 내가 쿼리를 작성하는 방법 확실하지 않다 난 그냥 지금 운동 할 시간이 있지만 변환 후 cumsum를 사용하여 우아한 솔루션 (X == 0이)가 상당히 확신하지

df %>% 
    arrange(brand) %>%       # order brands to have a better visualisation 
    group_by(brand) %>%       # group by brand and create (on the background) 5 sub-datasets based on each brand (see the Groups: brand [5]) 
    mutate(Counter = sum(!is.na(isExist))) %>% # count how many times you have non NA values, based on a brand, and add it as a column while keeping all rows (this is like counting and joining back to the original dataset at the same time) 
    filter(Counter == 0) %>%     # keep only rows with Counter = 0 (those are the ones with only NA values) 
    ungroup()         # forget the grouping 
+0

감사합니다.이 쿼리가 작동합니다. 필터 후, 그것은 NA가없는 값만 선택합니다. 그래서 FB와 Oracle이 NA 값을 가진 그림으로 된 방법은 – Vineet

+0

예, 자세한 정보로 답변을 업데이트하겠습니다. – AntoniosK

+0

is.n은 마치 합계의 범위 내에서만 작동하므로 예외가 발생하지 않으며 기본 쿼리를 필터링하지 않습니다. 따라서 OOPS 및 SQL 백그라운드에서부터 그렇게 생각합니다. 이제는 쿼리를 이해합니다 ... 나는이 문제를 처리하는 방법에 깊은 인상을 받았다. 매우 두렵다. – Vineet