2017-12-01 3 views
3

これを行うには、より洗練された、よりclunkyで速い方法があるのだろうかと思っていました。私は、臨床データをコードするICDを持つ何百万もの行を持っています。以下に簡単な例を示します。私は特定の診断コードセットに合ったいずれかの列に基づいてデータセットをサブセット化しました。以下のコードは動作しますが、Rで年月を要し、より高速な方法があるかどうか疑問に思っていました。data.tableを使用して複数の列に基づいて行をサブセット化する - 最速の方法

structure(list(eid = 1:10, mc1 = structure(c(4L, 3L, 5L, 2L, 
1L, 1L, 1L, 1L, 1L, 1L), .Label = c("345", "410", "413.9", "I20.1", 
"I23.4"), class = "factor"), oc1 = c(350, 323, 12, 35, 413.1, 
345, 345, 345, 345, 345), oc2 = structure(c(5L, 6L, 4L, 1L, 1L, 
2L, 2L, 2L, 3L, 2L), .Label = c("", "345", "I20.3", "J23.6", 
"K50.1", "K51.4"), class = "factor")), .Names = c("eid", "mc1", 
"oc1", "oc2"), class = c("data.table", "data.frame"), row.names = c(NA, 
-10L), .internal.selfref = <pointer: 0x102812578>) 

サブセット以下のコード「I20」又は「413」のいずれかのコードを満たすすべての行(これは、例えば、等「I20.4」または「413.9」として符号化されたすべてのコードを含むであろう

dat2 <- dat [substr(dat$mc1,1,3)== "413"| 
      substr(dat$oc1,1,3)== "413"| 
      substr(dat$oc2,1,3)== "413"| 
      substr(dat$mc1,1,3)== "I20"| 
      substr(dat$oc1,1,3)== "I20"| 
      substr(dat$oc2,1,3)== "I20"] 

これを行うためのより高速な方法は、たとえば、私は、ループ特定のコード「I20」または「413」を探している列のそれぞれを通って、それらの行をサブセットできますか?ありますか?

+1

https://cran.r-project.org/web/packages/icd/index.htmlに気づいていますか? – Hugh

+0

問題はカラムが文字フォーマットになっていないことです。データを読み込むときにフォーマットを指定すると、 'substr'がはるかに高速になります。 – minem

答えて

1

私たちは、指定することができます関心のある列は.SDcolsにあり、Data.tableのサブセットをループします(.SD )、我々はすべての行をchechいけない場合には、行、それは助けることができる大規模データについては

dat[dat[,Reduce(`|`, lapply(.SD, function(x) 
      substr(x, 1, 3) %chin% c('413', 'I20'))), .SDcols = 2:4]] 
# eid mc1 oc1 oc2 
#1: 1 I20.1 350.0 K50.1 
#2: 2 413.9 323.0 K51.4 
#3: 5 345 413.1  
#4: 9 345 345.0 I20.3 
+2

Akrun - あなたはトップマンです!魅力的な作品! – user3919790

0

をサブセット化のための%in%値のvectorと単一の論理vectorからReduceそれをあるかどうかをチェックし、substrで最初の3文字を取得します:

minem <- function(dt, colsID = 2:4) { 
    cols <- colnames(dt)[colsID] 
    x <- c('413', 'I20') 
    set(dt, j = "inn", value = F) 
    for (i in cols) { 
    dt[inn == F, inn := substr(get(i), 1, 3) %chin% x] 
    } 
    dt[inn == T][, inn := NULL][] 
} 

n <- 1e7 
set.seed(13) 
dt <- dts[sample(.N, n, replace = T)] 
dt <- cbind(dt, dts[sample(.N, n, replace = T), 2:4]) 
setnames(dt, make.names(colnames(dt), unique = T)) 
dt 
#   eid mc1 oc1 oc2 mc1.1 oc1.1 oc2.1 
#  1: 8 345 345.0 345 345 345 345 
#  2: 3 I23.4 12.0 J23.6 413.9 323 K51.4 
#  3: 4 410 35.0  413.9 323 K51.4 
#  4: 1 I20.1 350.0 K50.1 I23.4 12 J23.6 
#  5: 10 345 345.0 345 345 345 345 
#  ---           
# 9999996: 3 I23.4 12.0 J23.6 I20.1 350 K50.1 
# 9999997: 5 345 413.1  I20.1 350 K50.1 
# 9999998: 4 410 35.0   345 345 345 
# 9999999: 4 410 35.0   410 35  
# 10000000: 10 345 345.0 345 345 345 I20.3 

system.time(r1 <- akrun(dt, 2:ncol(dt))) # 22.88 sek 
system.time(r2 <- minem(dt, 2:ncol(dt))) # 17.72 sek 
all.equal(r1, r2) 
# [1] TRUE 
関連する問題