2014-12-31 3 views
0

일부 설문 조사 결과가 있으며 기본 교차 표를 만들려고합니다. 각 열은 일종의 화학 물질이며 숫자 0 : 5는 그 화학 물질이 얼마나 유용했는지 나타냅니다.설문 조사에서 범주 형 변수의 데이터 프레임에서 크로스 탭 생성

저는 주파수와 퍼센트를 나타내는 멋진 테이블을 찾으려고합니다. 테이블 또는 xtabs를 사용하여 각 열에 대해 개별 결과를 얻을 수 있지만, 모든 화학 물질을 포함하는 라텍스로 출력 할 수있는 멋진 테이블을 만드는 방법을 알아 내고 싶습니다. 표.

도움을 주셔서 감사합니다.

데이터 프레임 :

df <- read.table(text = " 
V1 V2 V3 V4 V5 V6 V7 
1 NA NA NA NA NA NA NA 
2 0 0 0 0 0 0 0 
3 0 0 0 0 0 0 NA 
4 NA NA NA NA NA NA 5 
5 0 0 0 0 0 2 0 
6 NA 4 NA NA NA NA NA 
7 0 0 0 0 0 0 0 
8 NA NA NA NA NA 3 NA 
9 NA 2 NA NA NA 3 NA 
10 NA 4 NA NA NA NA NA 
11 0 0 0 0 0 0 0 
12 0 0 0 0 0 0 0 
13 0 0 0 0 0 0 0 
14 NA NA NA NA NA 2 3 
15 NA 3 NA 3 NA NA NA 
16 NA 4 NA NA NA NA NA 
17 0 0 0 0 0 0 0 
18 NA 5 NA 5 NA NA NA 
19 0 0 0 0 0 0 0 
20 NA 1 NA NA NA NA NA", header = T) 

원하는 출력 (V1 및 V2에 대한 정확한 번호) : 여기

     V1   V2   etc.... 
        Freq Percent Freq Percent 
No     9  100  9 56.2 
Poor    0  0  1 6.2 
Somewhat effective 0  0  1 6.2 
Good    0  0  1 6.2 
Very Good   0  0  3 18.75 
NA     0  0  1 6.2 
+0

@Amstell 이러한 분류에 대한 차단 제한은 무엇입니까? – akrun

+0

@Ujjwal 작은 하위 집합을 만들었으므로 데이터의 게시물 데이터 프레임 섹션을 참조하십시오. – Vedda

+0

@akrun 차단 한도 란 무엇입니까? 숫자는 0에서 5까지 0이 아닌 숫자로 표시됩니다. – Vedda

답변

3

, 우리는 lapplytable를 사용하여 각 열에 대한 주파수를 얻고있다. lapplylist 환경에서 data.frame을 얻은 다음 0:5으로 지정된 수준의 열을 factor으로 변환 한 후 table을 사용합니다. 사용, prop.table 비율을 얻기 위해, cbindFreqPercentlist 마지막으로 do.call(cbind에 의해 data.frame, 그리고에 row.namescolnames

res <- do.call(cbind,lapply(df, function(x) { 
      x1 <- table(factor(x, levels=0:5, 
       labels=c('No', 'Poor', 'Somewhat Effective', 
           'Good', 'Very Good', 'NA'))) 
      cbind(Freq=x1, Percent=round(100*prop.table(x1),2))})) 
colnames(res) <- paste(rep(paste0('V',1:7),each=2), 
            colnames(res),sep=".") 

    head(res,2) 
    #  V1.Freq V1.Percent V2.Freq V2.Percent V3.Freq V3.Percent V4.Freq 
    #No   9  100  9  56.25  9  100  9 
    #Poor  0   0  1  6.25  0   0  0 
    #  V4.Percent V5.Freq V5.Percent V6.Freq V6.Percent V7.Freq V7.Percent 
    #No  81.82  9  100  8  66.67  8   80 
    #Poor  0.00  0   0  0  0.00  0   0 
+0

이것은 감사했습니다. .. 가능하다면 기능이있는 첫 번째 부분을 설명해주십시오. 감사! – Vedda

+0

@Amstell 예, 나는 게시물을 업데이트 할 것입니다 – akrun

+0

도움을 많이 주셔서 감사합니다. 결코이 길로 갈 생각은 없었습니다.하지만 배울 것이 좋습니다 .. 다시 감사합니다. – Vedda

2

내가 정기적으로 "dplyr"또는 "tidyr"사용자 아니에요 이름을 변환 그래서이 그 도구를 사용하여 가장 좋은 방법이 아닌 경우 확신 (그러나 작동하는 것 같다) :

library(dplyr) 
library(tidyr) 
df %>% 
    gather(var, val, V1:V7) %>%    ## Make the data long 
    na.omit() %>%       ## We don't need the NAs 
    ## Factor the "value" column 
    mutate(val = factor(val, 0:5, c("No", "Poor", "Somewhat Effective", 
            "Good", "Very Good", "NA"))) %>% 
    group_by(val, var) %>%     ## Group by val and var 
    summarise(Freq = n()) %>%    ## Get the count 
    group_by(var) %>%      ## Group just by var now 
    mutate(Pct = Freq/sum(Freq) * 100) %>% ## Calculate the percent 
    gather(R1, R2, Freq:Pct) %>%   ## Go long again.... 
    unite(Var, var, R1) %>%     ## Combine the var and R1 cols 
    spread(Var, R2, fill = 0)    ## Go wide.... 
# Source: local data frame [6 x 15] 
# 
#     val V1_Freq V1_Pct V2_Freq V2_Pct V3_Freq V3_Pct V4_Freq 
# 1     No  9 100  9 56.25  9 100  9 
# 2    Poor  0  0  1 6.25  0  0  0 
# 3 Somewhat Effective  0  0  1 6.25  0  0  0 
# 4    Good  0  0  1 6.25  0  0  1 
# 5   Very Good  0  0  3 18.75  0  0  0 
# 6     NA  0  0  1 6.25  0  0  1 
# Variables not shown: V4_Pct (dbl), V5_Freq (dbl), V5_Pct (dbl), V6_Freq 
# (dbl), V6_Pct (dbl), V7_Freq (dbl), V7_Pct (dbl) 

은 "data.table" 접근법은 일련의 단계를 거쳐야 유사합니다.

library(data.table) 
library(reshape2) 
levs <- c("No", "Poor", "Somewhat Effective", "Good", "Very Good", "NA") 
DT <- melt(as.data.table(df, keep.rownames = TRUE), 
      id.vars = "rn", na.rm = TRUE) 
DT <- DT[, value := factor(value, 0:5, levs) 
     ][, list(Freq = .N), by = list(variable, value) 
      ][, Pct := Freq/sum(Freq) * 100, by = list(variable)] 
dcast.data.table(melt(DT, id.vars = c("variable", "value")), 
       value ~ variable + variable.1, 
       value.var = "value.1", fill = 0) 

확인을 한 번 더 ... (@ akrun의 대답에 변형)

library(gdata)  ## For "interleave" 
levs <- c("No", "Poor", "Somewhat Effective", "Good", "Very Good", "NA") 
x1 <- sapply(lapply(df, factor, 0:5, levs), table) 
t(interleave(t(x1), t(prop.table(x1, 2)))) 

### Or, skipping the transposing.... 
## library(SOfun) ## For "Riffle" which is like "interleave" 
## Riffle(x1, prop.table(x1, 2) * 100) 
+0

고마워요! 나는 dplyr와 tidyr .....에서 이것을 어떻게하는지 궁금하게 생각하고 있었다.나는 신중하게 이것을 보겠습니다. – Vedda

+0

@AnandaMahto 포인터를 보내 주셔서 감사합니다. 출력을 변경했습니다. 자, 일관성이 있다고 생각합니다. 'dplyr'의 경우 (+1) – akrun

관련 문제