2016-11-08 9 views
-4

열 x $ id의 값에 따라 하위 집합을 반환하는 함수를 제공하는 dataframe --say x -이 있습니다.반환 된 열을 미리 알 수없는 경우 그룹화 및 요약

이 하위 집합 y에는 x $ id 값에 따라 다른 값 조합이 포함 된 열 y $ room이 포함됩니다.

그런 다음 하위 집합을 깔끔하게 펼치고 y $ 방의 값이 열이됩니다.
그런 다음 확장 된 df -say ext_y--는 y_ext $ visit 열로 그룹화되어야하고 요약 통계는 특수 함수를 통해 나머지 열에 대해 계산되어야합니다.

명백한 문제는 이러한 열은 미리 알 수 없으므로 함수 내에서 이름으로 정의 할 수 없다는 것입니다.

group_by가 관련되어있을 때 이름 대신 열의 색인을 사용하는 대신 dplyr을 사용할 수 없습니다.

이 문제의 해결 방법에 대해 알고 싶습니까?

dataframe는 수천 행을 가지고, 그래서 당신에게 만 살짝 줄 것이다 : 주어진 ID에 대한 tidyr의 x 객실의 값의 일부를 반환() 확산을

 > tail(y) 
      id visit  room value 
    11940 14  2 living room 19 
    11941 14  2 living room 16 
    11942 14  2 living room 15 
    11943 14  2 living room 22 
    11944 14  2 living room 25 
    11945 14  2 living room 20 

    > unique(x$id) 
    [1] 14 20 41 44 46 54 64 74 104 106 
    > unique(x$visit) 
    [1] 0 1 2 
    > unique(x$room) 
    [1] "bedroom"  "living room" "family room" "study room" "den"   
    [6] "tv room"  "office"  "hall"   "kitchen"  "dining room" 
    > summary(x$value) 
     Min. 1st Qu. Median  Mean 3rd Qu.  Max. 
     2.000 2.750 7.875 17.410 16.000 1775.000 

합니다. 예 : ID = 54 : 이제

> y<- out 
    > y$row <- 1 : nrow(y) 
    > y_ext <- spread(y, room, value) 
    > head(y_ext) 
     id visit row bedroom family room living room 
    1 14  0 1 6.00   NA   NA 
    2 14  0 2 6.00   NA   NA 
    3 14  0 3 2.75   NA   NA 
    4 14  0 4 2.75   NA   NA 
    5 14  0 5 2.75   NA   NA 
    6 14  0 6 2.75   NA   NA 

, 그 그룹을 방문하여 그 결과를 함수를 작성하고 다음과 같은 형태로 각 그룹에 대해 반환되는 열을 요약합니다

  visit bedroom family room living room 
     1 0   NA   2.79   3.25 
     2 1   NA    NA   4.53 
     3 2   4.19   3.77  NA 

내가 언급 한 바와을 위에서 주어진 id에 대해 어떤 열이 반환 될지 미리 알지 못하기 때문에 문제가 복잡해집니다. 물론 각각의 ID가 반환되는 단축키를 확인한 후 이 될 것이고구조를 만들면 각 코드를 적절한 코드로 안내 할 수 있지만 매우 우아하지는 않습니다. 두렵습니다.

희망이 있으면 더 나은 그림을 얻을 수 있습니다.

nSamples <- 50 

allRooms <- 
    c("Living", "Dining", "Bedroom", "Master", "Family", "Garage", "Office") 

set.seed(8675309) 

df <- 
    data_frame(
    id = sample(1:5, nSamples, TRUE) 
    , visit = sample(1:3, nSamples, TRUE) 
    , room = sample(allRooms, nSamples, TRUE) 
    , value = round(rnorm(nSamples, 20, 5)) 
) 

내가 볼때, reasonabality의 오름차순으로 세 가지 방법이있다 :

+1

환영을 제공합니다 (예를 들어, 인쇄 할 때, 다음, 당신은 가능성이 한 번 출력을 절약 할 수, 주 관심의 각 ID에 대해 한 번 마지막 두 줄을 통해 그것을 통과)! [좋은 질문을하는 법] (http://stackoverflow.com/help/how-to-ask) 및 [재현 가능한 예] (http://stackoverflow.com/questions/)에 대한 정보를 읽어보십시오. 5963269). 이렇게하면 다른 사람들이 당신을 도울 수있게됩니다. – zx8754

+1

대신 우리에게 문제를 말하면, 문제를 해결하는 데 도움이되는 예제 데이터 세트를 제공하는 것이 일반적입니다. 그것이 없다면 항상 같은 수의 열이 선택되어 있습니까? 예를 들어 피쳐로 선택하기 위해 사용할 수있는 이름의 패턴이 있습니까? 공통적 인 시나리오가 있습니까? 위의 모든 문제를 수정하면 우리가 할 수있는 일이 나와 있습니다. –

+0

의견에 감사드립니다. 코드와 데이터를 추가했습니다. 이것이 당신이 문제를 더 잘 이해하는 데 도움이되기를 바랍니다. 질문을 더 향상시킬 수 있는지 알려 주시기 바랍니다. 더욱이 가능한 한 질문의 채점을 개선하여 미래에 새로운 문제를 제기하는 데 문제가 발생하지 않도록하십시오. – pv7

답변

1

좋아, 이건 좀 샘플 데이터 나 자신을 만들어 나에게 충분히 흥미로웠다. 첫 번째 옵션은 기본 레이아웃을 따르는 것입니다. 여기에서 dfid으로 분할하고 지시에 따라 전파 한 다음 summarise_all을 사용하여 회의실 이름을 명시 적으로 식별하지 않아도됩니다.

df %>% 
    split(.$id) %>% 
    lapply(function(x){ 
    x %>% 
     select(-id) %>% 
     mutate(row = 1:n()) %>% 
     spread(room, value) %>% 
     select(-row) %>% 
     group_by(visit) %>% 
     summarise_all(sum, na.rm = TRUE) 
    }) 

는 다음 (주의 독특한 열) 반환 그러나

$`1` 
# A tibble: 3 × 6 
    visit Bedroom Dining Garage Master Office 
    <int> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  1  0  27  27  0  0 
2  2  22  19  0  20  23 
3  3  0  0  0  27  0 

$`2` 
# A tibble: 3 × 6 
    visit Bedroom Dining Family Living Office 
    <int> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  1  15  0  0  0  17 
2  2  0  14  42  30  0 
3  3  15  13  18  0  20 

$`3` 
# A tibble: 3 × 6 
    visit Bedroom Dining Living Master Office 
    <int> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  1  24  0  36  0  28 
2  2  0  0  15  30  0 
3  3  0  25  21  0  15 

$`4` 
# A tibble: 3 × 7 
    visit Bedroom Dining Garage Living Master Office 
    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  1  0  0  23  20  0  24 
2  2  0  28  22  0  0  0 
3  3  24  0  36  0  16  0 

$`5` 
# A tibble: 3 × 8 
    visit Bedroom Dining Family Garage Living Master Office 
    <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  1  23  0  0  21  0  16  0 
2  2  44  14  41  0  26  0  18 
3  3  21  19  0  0  25  19  0 

, 당신이 spread 일하러에 행을 추가했기 때문에 (그것없이, 고유 한 항목이 없습니다) spread은 실제로 도움이되지 않습니다.먼저, 요약을 할 경우에는과 같이보다 쉽게 ​​같은 일을 많이 얻을 수는 fill 인수로 인해 마지막 0없이 방문 객실에 대한 0을 제공

df %>% 
    split(.$id) %>% 
    lapply(function(x){ 
    x %>% 
     select(-id) %>% 
     group_by(visit, room) %>% 
     summarise(Sum = sum(value)) %>% 
     spread(room, Sum, 0) 
    }) 

하는 것으로. 오히려 NA을 반환하는 경우 기본값을 그대로 둘 수 있습니다.

마지막으로 왜 처음부터 별도로이 작업을 수행하려고하는지 명확하지 않습니다. 이 모든 것을 하나의 큰 group_by에서 수행하고 사실 이후 필요에 따라 누락을 처리하는 것이 훨씬 더 합리적 일 수 있습니다. 지혜롭게 말하자면 동일한 요약을 얻는 데 필요한 코드가 훨씬 적습니다. 당신이 한 id까지 필터링 사후 filter을 사용하여, 모든 NA 항목과 열을 제거하려면

df %>% 
    group_by(id, visit, room) %>% 
    summarise(sum = sum(value)) %>% 
    spread(room, sum) 

 id visit Bedroom Dining Family Garage Living Master Office 
* <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  1  1  NA  27  NA  27  NA  NA  NA 
2  1  2  22  19  NA  NA  NA  20  23 
3  1  3  NA  NA  NA  NA  NA  27  NA 
4  2  1  15  NA  NA  NA  NA  NA  17 
5  2  2  NA  14  42  NA  30  NA  NA 
6  2  3  15  13  18  NA  NA  NA  20 
7  3  1  24  NA  NA  NA  36  NA  28 
8  3  2  NA  NA  NA  NA  15  30  NA 
9  3  3  NA  25  NA  NA  21  NA  15 
10  4  1  NA  NA  NA  23  20  NA  24 
11  4  2  NA  28  NA  22  NA  NA  NA 
12  4  3  24  NA  NA  36  NA  16  NA 
13  5  1  23  NA  NA  21  NA  16  NA 
14  5  2  44  14  41  NA  26  NA  18 
15  5  3  21  19  NA  NA  25  19  NA 

제공합니다.

df %>% 
    group_by(id, visit, room) %>% 
    summarise(sum = sum(value)) %>% 
    spread(room, sum) %>% 
    filter(id == 1) %>% 
    select_if(function(col) mean(is.na(col)) != 1) 

은 스택 오버플로

 id visit Bedroom Dining Garage Master Office 
    <int> <int> <dbl> <dbl> <dbl> <dbl> <dbl> 
1  1  1  NA  27  27  NA  NA 
2  1  2  22  19  NA  20  23 
3  1  3  NA  NA  NA  27  NA 
+0

Mark thank you 이 철저한 대답을 위해서. 귀하의 코드를 실행할 때 몇 가지 오류 메시지가 나타납니다. 첫 번째 부분을 실행할 때 "오류 (n) 오류 :이 함수를 직접 호출하면 안됩니다."라는 오류 메시지가 나타납니다. 두 번째와 세 번째 파트를 실행할 때 "오류 : 키 열 'room'이 입력에 없습니다."라는 오류 메시지가 나타납니다. 이 오류는 summarize 절 다음에 나타납니다. 그런데 "Reference Classes 패러다임을 사용하여 R로 클래스 정의"라는 제목의 질문을 게시했습니다. 당신이 볼 수 있고 당신이 대답을 줄 수 있는지 알 수 있다면 가능할 수 있습니까? – pv7

+0

내가 당신을 위해 만든 재현 가능한 데이터에 포함 할 샘플의 수를 설정하는 부분을 포함하지 않았다. 내가 (지금 질문에) 그것을 포함 시키면, 그 외 모든 것은 예상대로 실행된다. 개별적으로 개별적으로 실행하려고합니까? –