2013-03-22 43 views
7

Tôi có khung dữ liệu và tôi đang cố gắng tạo biến mới trong khung dữ liệu có số lượng của biến số liên tục var1, cho mỗi cấp của một hệ số strata.Số lượng theo các mức hệ số trong R

# some data 
set.seed(472) 
dat <- data.frame(var1 = rnorm(50, 10, 3)^2, 
        strata = factor(sample(LETTERS[1:5], size = 50, replace = TRUE)) 
       ) 

# function to get quantiles 
qfun <- function(x, q = 5) { 
    quantile <- cut(x, breaks = quantile(x, probs = 0:q/q), 
     include.lowest = TRUE, labels = 1:q) 
    quantile 
} 

Tôi đã thử sử dụng hai phương pháp, không tạo ra kết quả khả dụng. Thứ nhất, tôi đã cố gắng sử dụng aggregate để áp dụng qfun với từng mức độ strata:

qdat <- with(dat, aggregate(var1, list(strata), FUN = qfun)) 

này trả về quantiles theo trình độ yếu tố, nhưng sản lượng khó có thể ép buộc trở thành một khung dữ liệu (ví dụ, sử dụng unlist không đường biến mới sẽ tăng giá trị với các hàng chính xác trong khung dữ liệu).

Một cách tiếp cận thứ hai là để làm điều này trong các bước:

tmp1 <- with(dat, split(var1, strata)) 
tmp2 <- lapply(tmp1, qfun) 
tmp3 <- unlist(tmp2) 
dat$quintiles <- tmp3 

Một lần nữa, điều này sẽ tính toán một cách chính xác quantiles cho mỗi cấp độ yếu tố, nhưng rõ ràng, như với aggregate họ không theo đúng thứ tự trong các dữ liệu khung. Chúng ta có thể kiểm tra điều này bằng cách đặt "thùng" số lượng tử vào khung dữ liệu.

# get quantile bins 
qfun2 <- function(x, q = 5) { 
    quantile <- cut(x, breaks = quantile(x, probs = 0:q/q), 
     include.lowest = TRUE) 
    quantile 
} 

tmp11 <- with(dat, split(var1, strata)) 
tmp22 <- lapply(tmp11, qfun2) 
tmp33 <- unlist(tmp22) 
dat$quintiles2 <- tmp33 

Nhiều người trong số các giá trị của var1 nằm ngoài thùng của quantile2. Tôi cảm thấy như tôi đang thiếu một cái gì đó đơn giản. Bất kỳ đề xuất sẽ được đánh giá rất cao.

Trả lời

8

Tôi nghĩ vấn đề của bạn là bạn không thực sự muốn tổng hợp, nhưng sử dụng ave, (hoặc data.table hoặc plyr)

qdat <- transform(dat, qq = ave(var1, strata, FUN = qfun)) 

#using plyr 
library(plyr) 

qdat <- ddply(dat, .(strata), mutate, qq = qfun(var1)) 

#using data.table (my preference) 


dat[, qq := qfun(var1), by = strata] 

tổng hợp thường ngụ ý trả lại một đối tượng đó là nhỏ hơn bản gốc. (Inthis trường hợp bạn đã nhận được một data.frame nơi x là một list của 1 phần tử cho mỗi tầng lớp nhân dân

+0

(+1) trong 3 phương pháp khác nhau – ndoogan

+0

@mnel cảm ơn rất nhiều tôi biết tôi phải được thiếu một cái gì đó đơn giản - tôi luôn luôn quên ' ave'. – Chris

1

Sử dụng ave trên khung dat dữ liệu của bạn đầy đủ ví dụ với dữ liệu mô phỏng của bạn và qfun chức năng:..

# some data 
set.seed(472) 
dat <- data.frame(var1 = rnorm(50, 10, 3)^2, 
       strata = factor(sample(LETTERS[1:5], size = 50, replace = TRUE)) 
      ) 

# function to get quantiles 
qfun <- function(x, q = 5) { 
    quantile <- cut(x, breaks = quantile(x, probs = 0:q/q), 
     include.lowest = TRUE, labels = 1:q) 
    quantile 
} 

Và bổ sung của tôi ...

dat$q <- ave(dat$var1,dat$strata,FUN=qfun) 
Các vấn đề liên quan