2016-05-30 16 views
9

Câu hỏi khó với cụm từ. Đây là một ví dụ về những gì tôi muốn làm. Một ví dụ về những gì tôi đang bắt đầu với:Nhóm theo một cột, chọn hàng có tối thiểu trong một cột cho mỗi cặp cột trong R

set.seed(0) 
dt <- data.table(dr1.d=rnorm(5), dr1.p=abs(rnorm(5, sd=0.08)), 
       dr2.d=rnorm(5), dr2.p=abs(rnorm(5, sd=0.08)), 
       dr3.d=rnorm(5), dr3.p=abs(rnorm(5, sd=0.08)), 
       dr4.d=rnorm(5), dr4.p=abs(rnorm(5, sd=0.08)), 
       sym = paste("sym", c(1,1,1,2,2))) 
dt 

     dr1.d  dr1.p  dr2.d  dr2.p  dr3.d  dr3.p  dr4.d  dr4.p sym 
1: 1.2629543 0.1231960034 0.7635935 0.03292087 -0.22426789 0.040288638 -0.2357066 0.09215294 sym 1 
2: -0.3262334 0.0742853628 -0.7990092 0.02017788 0.37739565 0.086861549 -0.5428883 0.07937283 sym 1 
3: 1.3297993 0.0235776357 -1.1476570 0.07135369 0.13333636 0.055276307 -0.4333103 0.03436105 sym 1 
4: 1.2724293 0.0004613738 -0.2894616 0.03485466 0.80418951 0.102767948 -0.6494716 0.09906433 sym 2 
5: 0.4146414 0.1923722711 -0.2992151 0.09900307 -0.05710677 0.003738094 0.7267507 0.02234770 sym 2 

Đối với tất cả các cặp cột có cùng một loại thuốc (ví dụ như 'DR1') Tôi muốn hàng nhóm bởi 'sym', sau đó chọn hàng với p-nhỏ nhất giá trị (kết thúc bằng '.p') trong mỗi nhóm. Kết quả cuối cùng của data.table trên sẽ là:

 dr1.d  dr1.p  dr2.d  dr2.p  dr3.d  dr3.p  dr4.d  dr4.p sym 
1: 1.3297993 0.0235776357 -0.7990092 0.02017788 -0.22426789 0.040288638 -0.4333103 0.03436105 sym 1 
2: 1.2724293 0.0004613738 -0.2894616 0.03485466 -0.05710677 0.003738094 0.7267507 0.02234770 sym 2 

Tôi đã cố gắng sử dụng .SD và lapply để thực hiện điều này, nhưng tôi không thể quấn quanh đầu tôi xung quanh nó. Cảm ơn bạn!

Trả lời

13

Điều quan trọng nhất (và mạnh mẽ) điều cần hiểu về data.table là, miễn là j trả về một danh sách , mỗi phần tử của danh sách sẽ trở thành một cột trong kết quả.

Với kiến ​​thức và một số cơ sở R niềm vui, chúng ta có thể có được kết quả này trực tiếp bằng cách thực hiện:

# I'm on v1.9.7, see https://github.com/Rdatatable/data.table/wiki/Installation 
cols1 = grep("d$", names(dt), value=TRUE) 
cols2 = grep("p$", names(dt), value=TRUE) 
dt[, Map(`[`, mget(c(cols1,cols2)), lapply(mget(cols2), which.min)), by=sym] 
#  sym dr1.d  dr2.d  dr3.d  dr4.d  dr1.p  dr2.p 
# 1: sym 1 1.329799 -0.7990092 -0.22426789 -0.4333103 0.0235776357 0.02017788 
# 2: sym 2 1.272429 -0.2894616 -0.05710677 0.7267507 0.0004613738 0.03485466 
#   dr3.p  dr4.p 
# 1: 0.040288638 0.03436105 
# 2: 0.003738094 0.02234770 

Xem vignettes để biết thêm.

2

Với một số nóng chảy và đúc này là khá đơn giản

library(data.table) 

set.seed(0) 
dt <- data.table(dr1.d=rnorm(5), dr1.p=abs(rnorm(5, sd=0.08)), 
       dr2.d=rnorm(5), dr2.p=abs(rnorm(5, sd=0.08)), 
       dr3.d=rnorm(5), dr3.p=abs(rnorm(5, sd=0.08)), 
       dr4.d=rnorm(5), dr4.p=abs(rnorm(5, sd=0.08)), 
       sym = paste("sym", c(1,1,1,2,2))) 


dt[, rowid := .I] #add a row identifier 
dt <- melt(dt, id.vars = c("sym", "rowid"), variable.factor = F) 

dt[, c("col","val") := tstrsplit(variable, "." , fixed = T)] #split the column so we can group 
dt[, variable := NULL] #small cleanup 


dt <- dcast(dt, sym + rowid + col ~ val) 
dt <- dt[, .SD[which.min(p)], by = .(sym,col)] #select min row 

dt[, rowid := NULL] #cleanup 

dt <- dcast(melt(dt, id.vars = c("sym","col")), sym ~ col + variable) 
dt 
     sym dr1_d  dr1_p  dr2_d  dr2_p  dr3_d  dr3_p  dr4_d  dr4_p 
1: sym 1 1.329799 0.0235776357 -0.7990092 0.02017788 -0.22426789 0.040288638 -0.4333103 0.03436105 
2: sym 2 1.272429 0.0004613738 -0.2894616 0.03485466 -0.05710677 0.003738094 0.7267507 0.02234770 
3

Dưới đây là một cách tiếp cận tất cả-trong-một, mặc dù bạn có thể muốn chia nó thành những bước riêng biệt để có thể đọc:

dcast(melt(dt, measure = patterns("\\.p$", "\\.d$"), id.vars = "sym", 
    value.name = c("p", "d"))[, .SD[which.min(p)], by = list(sym, variable)], 
    sym ~ variable, value.var = c("p", "d")) 
#  sym   p_1  p_2   p_3  p_4  d_1  d_2   d_3  d_4 
#1: sym 1 0.0235776357 0.02017788 0.040288638 0.03436105 1.329799 -0.7990092 -0.22426789 -0.4333103 
#2: sym 2 0.0004613738 0.03485466 0.003738094 0.02234770 1.272429 -0.2894616 -0.05710677 0.7267507 

Đó là về cơ bản tan chảy bởi hai mẫu đầu tiên, sau đó giảm dần theo giá trị p tối thiểu, sau đó dcasting trở lại định dạng rộng.

Các vấn đề liên quan