2015-01-14 3 views
4

R 3.1.2, dplyr 0.4.0을 사용합니다.dplyr에서 필터 내부의 필터를 사용하면 예기치 않은 결과가 발생합니다.

나는 filter 내에서 filter을 사용하려고하는데, 이는 매우 간단하게 들리며 왜 내가 기대 한 결과를주지 않는지 이해할 수 없습니다. 이것은 약 6 개월 전에 작성한 코드이며 제대로 작동하는지 확신 할 수 있으므로 업데이트 된 R 버전 또는 dplyr 또는 다른 종속성으로 인해 작업이 중단됩니다. 어쨌든, 다음은 df2의 열에서 filter으로 발견되는 조건을 기반으로 df1의 행을 필터링하는 간단한 코드입니다.

df1 <- data.frame(x = c("A", "B"), stringsAsFactors = FALSE) 
df2 <- data.frame(x = "A", y = TRUE, stringsAsFactors = FALSE) 
dplyr::filter(df1, x %in% (dplyr::filter(df2, y)$x)) 

나는이 df1의 첫 번째 행을 표시 할 것으로 예상, 대신 내가의 만들 모르겠어요

# [1] x 
# <0 rows> (or 0-length row.names) 

를 얻을. 벡터와 빈 data.frame을 반환하는 이유는 무엇입니까? 나는 두 개의 문에 필터 코드를 깰 경우

, 나는 내가 기대하는 것을 얻을이 문제가 발생하는 이유

xval <- dplyr::filter(df2, y)$x 
dplyr::filter(df1, x %in% xval) 

# x 
# 1 A 

사람이 저를 알아내는 데 도움이 할 수

? 나는 그것이 버그라고 말하는 것이 아니라 그것을 이해하지 못한다.

+0

난 정말 * 이유 *하지만'필터 (DF1, X %에서 % (필터를 설명 할 수 없다 (df2, y) %> %. $ x))'dplyr' 문법의 관점에서 더 적절하게 보이고, 원하는 결과물을 출력합니다. –

+0

그래, 나는 그걸 알아 차렸지만 좀 더 장황하고 작은 비트로 보인다. 덜 읽을 수있는 (논쟁의 여지가 있지만).그러나 나는 당신의 대답을 받아 들일 것입니다. 당신은 또한 제가 항상 가지고있는 또 다른 질문에 대답합니다 - 열을 추출하는 적절한 dplyr 방법은 무엇입니까? 때로'filter (df2, y) %> % select (x) %> % as.character' 또는'filter (df2, y) %> % select (x) %> % first'를 사용했습니다. –

+0

@RichardScriven, 당신이 dplyr 0.4.0을 사용하고 있다고 가정합니까? 0.3.0.2에서는 분명히 작동하지 않습니다. 또 다른 옵션은'filter (df2, y) %> % select (x) %> % inner_join (df1)' –

답변

4

당신의 접근 방식이 더 이상 효과가없는 이유는 무엇입니까? 나는 대답 할 수 없다. 그러나 위와 같이 다른 접근법을 제안 할 것이다. 중첩 된 함수 호출 (filter안에 또 다른 filter)은 IMO가 dplyr를 위해 만든 것이다. 읽기 쉽고 이해하기 쉽도록 표현하고있다. 문법, 왼쪽에서 오른쪽, 위에서 아래로. 둘 다 이름이 지정됩니다 관심있는 열 때문에 그래서 예를 들면

는 "X"당신은 할 수 있습니다 :

filter(df2, y) %>% select(x) %>% inner_join(df1) 
  • 필터 DF2 데이터를 "Y"열을 기준으로
  • 에만 열을 선택합니다 "x"
  • 공용 열 ("x")에서 df1로 inner_join을 수행하십시오. inner_join은 "y에서 일치하는 값이있는 x에서 모든 행을 반환하고 x와 y에서 모든 열을 반환합니다." 서로 다른라면

그리고, 예를 들어 "Z"를 위해 "x"는 다음과 같이 사용할 수 있습니다

filter(df2, y) %>% select(x) %>% inner_join(df1, by = c("z" = "x")) 
아래 자신의 의견에 해들리에 의해 언급 한 바와 같이

, 그것을 사용하는 것이 더 안전 할 것 여기서 inner_join 대신 semi_join입니다. 문서는 말한다 :

semi_join: return all rows from x where there are matching values in y, keeping just columns from x.

A semi join differs from an inner join because an inner join will return one row of x for each matching row of y, where a semi join will never duplicate rows of x.

을 따라서, 당신은 예를 들어, 경우에 할 수있는 :

filter(df2, y) %>% select(x) %>% semi_join(df1) 
+1

'semi_join()'은 여기 'inner_join()'보다 안전합니다. – hadley

+0

@hadley, 그건 의미가 있습니다. 내 대답을 업데이 트하고 sem_join에 대한 설명서가 포함되어 있습니다. –

관련 문제