使用R映射多个ID

时间:2013-06-20 20:16:19

标签: r lookup-tables

这个想法如下。每位患者都有一个独特的患者ID,我们称之为 hidenic_id 。然而,该患者可能多次入院。另一方面,每个条目都有唯一的 emtek_id

患者110380于4/14/2001 11:08入院,然后转院并于4/24/2001 18:16出院。现在,这名患者于5/11/2001 23:24再次入院,因为他现在有不同的emtek_id。他于5/25/2001 16:26出院。因此,您需要通过检查日期来分配正确的emtek_ids。如果合并文件中的日期在入场和出院时间段内(或非常接近24小时),我们可以指定emtek_id。

如何为具有hidenic_id和允许时间的条目指定不同的emtek_ID?

2 个答案:

答案 0 :(得分:1)

我有几个值得分享的想法。

首先,根据hidenic_id和date设置emtek_id。其次,使emtek_id具有逻辑解析性,例如emtek_id @ dataTime。第三,使数据库成为全局向量。根据内存限制,必须有一种比这更快的方法,但这可能会给您一些想法。

主要问题是处理NA值和不正确的hidenic_id,验证hidenic_id,并在不使用字符开头的情况下填充ID(这将是一个快速解决方案)。最后,您要如何处理不正确但不是NA / Null的输入?例如,假设您输入“ ID”而不是“ ID12345”,是否要将其视为分配新值的调用或提示输入正确的XOR NA值?我将假设您仅向其提供正确的ID输入或NA值,但这是我的琐碎假设。

这里有一些伪代码可以启动这个想法。您选择存储数据的方式(例如,csv文件,然后使用data.table :: fread()):

#this file's name is "make.hidenic_id.R"
library(data.table)
library(stringr)
set.seed(101)
#one might one a backup written, perhaps conditionally updating it every hour or so.
database.hidenic_id <<-data.table::fread("database.filename.hidenic_id.csv")
database.emtek_id   <<-data.table::fread("database.filename.emtek_id.csv") 

make.hidenic_Id = function(in.hidenic_id){
            if(is.na(in.hidenic_id) | !(in.hidenic_id %in% database.hidenic_id)){
                new.hidenic_id=NA
                #conditionally make new hidenic_id
                while( new.hidenic_id %in% database.hidenic_id){
                    new.hidenic_id = paste0("ID",str_pad(sample.int(99999, 1),5,pad=0))
                }
                #make new emtek_id
                new.emtek_id <- paste0(new.hidenic_id,  sep="@",  str_sub(Sys.time(),1,16))
                
                #update databases; e.g., c(database.emtek_id, new.emtek_id)
                database.hidenic_id <<- c(database.hidenic_id, new.hidenic_id)
                database.emtek_id   <<- c(database.emtek_id,   new.emtek_id)
            }else{
                new.emtek_id <- paste0(in.hidenic_id,  sep="@",  str_sub(Sys.time(),1,16))
              # update database.emtek_id 
              database.emtek_id   <<- c(database.emtek_id,   new.emtek_id)  
            }
            return(new.emtek_id)
}
temp = readline(prompt="Enter hidenic_id OR type \"NA\": ")
data.table::fwrite(database.emtek_id,  "database.filename.emtek_id.csv") 
data.table::fwrite(database.hidenic_id,"database.filename.hidenic_id.csv") 

并使用

调用文件
source("make.hidenic_id.R") 

对于管理不良的输入数据或优化搜索,我没有做很多“好的做法”,但这是一个好的开始。其他一些好的做法是使用更长的整数或不同的前导字符串,但是您从未说过我们可以使用输入值来创建ID。

您可以说这是受到普查启发的,因为每个地理ID变量都只是一个大字符串。

答案 1 :(得分:0)

我对你的问题很感兴趣,所以我创建了一些模拟数据并试图解决问题,但我自己遇到了一些困惑然后发布了我的问题,我认为这是你要问的但更一般。您可以在此处查看回复:How can I tell if a time point exists between a set of before and after times

我的帖子产生了我认为你开始的东西,并且检查的答案是我认为你正在寻找的。完整代码如下。您需要安装zooIRanges。 另外,我在版本2.15.3中这样做了。 IRanges未在3.0.0中正确安装。

## package installation
source("http://bioconductor.org/biocLite.R")
  biocLite("IRanges")
install.packages("zoo")


## generate the emtek and hidenic file data
library(zoo)
date_string <- paste("2001", sample(12, 10, 3), sample(28,10), sep = "-")
time_string <- c("23:03:20", "22:29:56", "01:03:30", "18:21:03", "16:56:26",
                 "23:03:20", "22:29:56", "01:03:30", "18:21:03", "16:56:26")

entry_emtek <- strptime(paste(date_string, time_string), "%Y-%m-%d %H:%M:%S")
entry_emtek <- entry_emtek[order(entry_emtek)]
exit_emtek <- entry_emtek + 3600 * 24
emtek_file <- data.frame(emtek_id = 1:10, entry_emtek, exit_emtek)

hidenic_id <- 110380:110479
date_string <- paste("2001", sample(12, 100, replace = TRUE), sample(28,100, replace = T), sep = "-")
time_string <- rep(c("23:03:20", "22:29:56", "01:03:30", "18:21:03", "16:56:26",
                 "23:03:20", "22:29:56", "01:03:30", "18:21:03", "16:56:26"),10)
hidenic_time <- strptime(paste(date_string, time_string), "%Y-%m-%d %H:%M:%S")
hidenic_time <- hidenic_time[order(hidenic_time)]
hidenic_file <- data.frame(hidenic_id, hidenic_time)

## Find the intersection of emtek and hidenic times.  This part was done by user: agstudy
library(IRanges)
## create a time intervals 
subject <- IRanges(as.numeric(emtek_file$entry_emtek),
        as.numeric(emtek_file$exit_emtek))
## create a time intervals (start=end here)
query <- IRanges(as.numeric(hidenic_file$hidenic_time),
        as.numeric(hidenic_file$hidenic_time))
## find overlaps and extract rows (both time point and intervals)  
emt.ids <- subjectHits(findOverlaps(query,subject))
hid.ids <- queryHits(findOverlaps(query,subject))
cbind(hidenic_file[hid.ids,],emtek_file[emt.ids,])