R中的外键式合并

时间:2012-07-07 02:41:37

标签: r

我正在合并一堆csv,每个id / pk / seqn有一行。

> full = merge(demo, lab13am, by="seqn", all=TRUE)
> full = merge(full, cdq, by="seqn", all=TRUE)
> full = merge(full, mcq, by="seqn", all=TRUE)
> full = merge(full, cfq, by="seqn", all=TRUE)
> full = merge(full, diq, by="seqn", all=TRUE)
> print(length(full$ridageyr))
[1] 9965
> print(summary(full$ridageyr))
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   0.00   11.00   19.00   29.73   48.00   85.00 

一切都很棒。但是,我有另一个文件,每个ID有多行,如:

"seqn","rxd030","rxd240b","nhcode","rxq250"
56,2,"","",NA,NA,""
57,1,"ACETAMINOPHEN","01200",2
57,1,"BUDESONIDE","08800",1
58,1,"99999","",NA

57有两行。所以,如果我天真地尝试合并这个文件,我会有更多行,而且我的数据都会变得歪斜。

> full = merge(full, rxq, by="seqn", all=TRUE)
> print(length(full$ridageyr))
[1] 15643
> print(summary(full$ridageyr))
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
   0.00   14.00   41.00   40.28   66.00   85.00 

是否有正常的惯用方法来处理这样的数据?例如,假设我想在full上创建一个列,其中包含参与者是否在过去30天内接受了RX。我可以通过以下方式获取密钥列表:

has_taken <- unique(rxq[rxq$rxd030 == "1",]$seqn)
hasnt_tak <- unique(rxq[rxq$rxd030 == "2",]$seqn)
full$takenRX <- ifelse(full$seqn %in% has_taken, TRUE, ifelse(full$seqn %in% hasnt_tak, FALSE, NA))

现在我有一个takenRX列,我认为我的full数据框中的每一行都正确给出了TRUE / FALSE / NA。我是否需要手动为每个数据位执行此类操作,还是有更自动化的方法可以将每个键的多行数据导入到我的数据框中?有更优雅的建议吗?更惯用的方法?

对于其他列,我想我想组合行,以便有〜元组。

key, a, b, c
2, 0, 0, 0

PLUS

key, baz
2, foo
2, bar

给了我类似的东西:

key, a, b, c, baz
2, 0, 0, 0, [foo, bar]

但是,我不确定用于[foo, bar]的数据结构是什么,因此我可以在以后使用“将boo中的foo”作为逻辑。

要在家里玩,有一些代码here

1 个答案:

答案 0 :(得分:3)

到您更新的示例:

demog <- data.frame(key=c(2, 3), a=c(1,0), b=letters[1:2], c=LETTERS[1:2])
meds <- data.frame(key=c(2,2), baz=c('foo', 'baz'), stringsAsFactors=FALSE)
aggregate(baz~key, data=meds, FUN=list)
#  key      baz
#1   2 foo, baz

merge(demog, mermed)
#  key a b c      baz
#1   2 1 a A foo, baz

如果您不想放弃没有药品的情况,您需要将all.x = TRUE添加到真实案例中。我对您的问题的批评部分是缺乏足够大的测试用例来揭露其他案例这样的编码缺陷。

> merge(demog, mermed, all.x=T)
  key a b c      baz
1   2 1 a A foo, baz
2   3 0 b B       NA

(我仍然认为以下情况适用。) 您可能需要构建一个合理的感兴趣药物分类,并为每个人级记录创建一个记录,记录他们是否从您研究的兴趣类别中选择一个。我想知道那些“rxd030”或“rxq250”代码是否可能是一种压缩降脂药的临床分组? (事实证明并非如此。)这表明提问者需要提供意义和代码才能获得合理的建议。

一些搜索表明这可能已经完成了。这是一篇来自NHANES 1999-2000网页的小药物:

Codebook

    SEQN - Respondent sequence number
    RXD030 - Taken prescription medicine/past month
    RXD240B - Standard generic ingredient name
    NHCODE - Standard generic ingredient code
    RXQ250 - Medicine container seen by interviewer
    RXD260 - Number of days taken medicine
    FDACODE1 - FDA/NDC drug class code 1 
    FDACODE2 - FDA/NDC drug class code 2
    FDACODE3 - FDA/NDC drug class code 3
    FDACODE4 - FDA/NDC drug class code 4
    FDACODE5 - FDA/NDC drug class code 5
    FDACODE6 - FDA/NDC drug class code 6

还有一个附录有一些重要性:

Code or Value   Value Description   Count   Cumulative  Skip to Item
Generic drug code   Value was recorded  9138     9138   
        < blank >   Missing             6505    15643 

其中一个医疗代码是:912 HYPERLIPIDEMIA

所以看起来你不需要重新发明轮子,而是可以使用已经完成的分类。

您首先需要根据“RXD030创建一个变量:您在过去一个月内服用或使用过任何处方药吗?”每个类别的“否”案例都为0。

我将数据输入R并查看了“高脂血症药物”。事实证明,只有FDACODE1和FDACODE2用于“0912”类别。以下是匹配的两个代码的前十个SEQN。我提供这个来帮助你构建一个合适的问题:

> subset( medrecs,  FDACODE2 %in% "0912" )[1:10,"SEQN"]
 [1]   46   86   90  191  434 1029 1273 1634 1980 2105
> subset( medrecs,  FDACODE1 %in% "0912" )[1:10,"SEQN"]
 [1]  29  55  86 130 148 179 187 211 239 274

一个正确的问题可以提供对部分或全部这些med记录的访问,以及一些没有它们的样本med记录,并且会有“demog”记录来匹配。