2017-11-21 8 views
1

행에 여러 값이있는 크로스 탭 테이블을 가져 와서 해당 행과 열의 순서를 지정할 수 있습니까?여러 열의 피벗/크로스 탭 데이터가 R

내가 필요한 크로스 탭은 빈도입니다.

만약 내가이 같은 크로스 탭 테이블을 결과를 얻을 수있는 방법

name abbr itemGroup 
abcd a  g1 
abcd a  g2 
bcde b  g1 
bcde b  g2 
abcd a  g3 
abcd a  g1 
bcde b  g2 
bcde b  g2 
bcde b  g2 

같은 데이터 프레임? 행이 정렬 된 경우 내림차순으로 각 행의 합계가 정렬되고 열은 왼쪽에서 오른쪽으로 내림차순으로 각 열의 합계로 정렬됩니다.

name abbr g2 g1 g3 total 
bcde b  4 1 0 5 
abcd a  1 2 1 4 
TOTAL   5 3 1 

답변

2

다음은 복잡한 tidyverse 접근 방식입니다.

library(tidyverse) #for dplyr, purrr, tibble, tidyr 

df <- tribble(
    ~name, ~abbr, ~itemGroup, 
    "abcd", "a",  "g1", 
    "abcd", 'a',  "g2", 
    "bcde", "b",  "g1", 
    "bcde", "b",  "g2", 
    "abcd", "a",  "g3", 
    "abcd", "a",  "g1", 
    "bcde", "b",  "g2", 
    "bcde", "b",  "g2", 
    "bcde", "b",  "g2" 
) 

order <- count(df, name, abbr, itemGroup) %>% 
    group_by(itemGroup) %>% 
    summarize(n = sum(n)) %>% 
    arrange(desc(n)) %>% 
    pull(itemGroup) 


df %>% 
    count(name, abbr, itemGroup) %>% 
    spread(itemGroup, n) %>% 
    left_join(group_by(df, name, abbr) %>% 
    summarize(total = n())) %>% 
    bind_rows(summarize_at(., vars(contains("g")), funs(sum), na.rm = TRUE) %>% 
       mutate(name = "TOTAL")) %>% 
    map_df(~replace(.x, is.na(.x), "")) %>% 
    arrange(desc(total)) %>% 
    select(name, abbr, one_of(order), total) 

결과

# A tibble: 3 x 6 
    name abbr g2 g1 g3 total 
    <chr> <chr> <chr> <chr> <chr> <chr> 
1 bcde  b  4  1   5 
2 abcd  a  1  2  1  4 
3 TOTAL   5  3  1  
  1. 제 2 비트는 DF를 형성 한 후, 전체 행의 열 순서를 결정한다.
  2. 이것은 각 항목을 계산하여 열로 확산하고, 열 요약에 결합하고, 행 요약을 바인드하고, NA을 ""로 대체하고, 전체 열을 정렬하고 나머지 열의 적절한 순서를 선택합니다.
+0

가! tidyverse가 mnormt에서 컴파일 오류로 인해 설치되지 않음 – Wanderer

+0

컴파일러가 gforgran 및 gcc로 변경됨 5가 차이를 만들었습니다 – Wanderer

+0

'outData $ total <-as.numeric을 제대로 처리하는 정렬 행을 얻으려면 한 걸음 더 가야했습니다. outData $ total)'outData <-outData %> %는 (desc (total))'을 다시 정렬합니다. 그렇지 않은 경우 999 개의 항목이있는 레코드가 10000 개의 항목보다 앞서있었습니다. – Wanderer