【问题标题】:moving values from one dataframe to another, depending on value of a variable根据变量的值将值从一个数据帧移动到另一个数据帧
【发布时间】:2012-05-02 06:39:24
【问题描述】:

不熟悉R,我遇到了以下问题:我想将数据框mlpa中的值probeposition添加到数据框patients中,probeposition的值通过值链接出现在mlpapatients 中(即probepatprobe)。据我所知,通常的数据管理教程没有涵盖这个问题。

#mlpa:
probe <- c(12,15,18,19)
probeposition <- c(100,1200,500,900)
mlpa = data.frame(probe = probe, probeposition = probeposition)
#patients:
patid <- c('AT', 'GA', 'TT', 'AG', 'GG', 'TA')
patprobe <- c(12, 12, NA, NA, 18, 19)
patients = data.frame(patid = patid, patprobe = patprobe)

#And that's what I finally want:
patprobeposition = c(100, 100, NA, NA, 500, 900)  
patients$patprobeposition = patprobeposition

更新

根据 Andrie 的回复,我意识到我必须提到患者数据集中有几个“探针”,所以实际上数据看起来更像这样(实际上,不仅有 probe1 和探针2,但探针1-探针4):

mlpa <- data.frame(probe = c(12,15,18,19),
                   probeposition = c(100,1200,500,900) ) 
patients <- data.frame(patid = c('AT', 'GA', 'TT', 'AG', 'GG', 'TA'),
                       probe1 = c(12, 12, NA, NA, 18, 19), 
                       probe2 = c(15, 15, NA, NA, 19, 19) )

而我想要的是这样的:

patients <- data.frame(patid = c('AT', 'GA', 'TT', 'AG', 'GG', 'TA'),   
                       probe1 = c(12, 12, NA, NA, 18, 19), 
                       probe2 = c(15, 15, NA, NA, 19, 19), 
                       position1 = c(100, 100, NA, NA, 500, 900), 
                       position2 = c(1200, 1200, NA, NA, 900, 900)) 

【问题讨论】:

    标签: r merge reshape


    【解决方案1】:

    您可以使用merge 轻松完成此操作,它采用两个数据框并将它们连接到共同的列或行名称上。

    merge 工作的最简单方法是确保您具有匹配的列名称,其中这些列引用相同的信息。具体来说,我已将您的专栏patprobe 重命名为probe

    mlpa <- data.frame(
      probe = c(12,15,18,19),
      probeposition = c(100,1200,500,900)
    )
    
    patients <- data.frame(
      patid = c('AT', 'GA', 'TT', 'AG', 'GG', 'TA'),
      probe = c(12, 12, NA, NA, 18, 19)
    )
    

    现在您可以致电merge。但是,请注意merge 的默认值只返回匹配的行(在数据库术语中,这是一个内连接)。您想要的是在patients (左外连接)中包含所有 行。您可以通过指定 all.x=TRUE 来做到这一点:

    merge(patients, mlpa, all.x=TRUE, sort=FALSE)
    
      probe patid probeposition
    1    12    AT           100
    2    12    GA           100
    3    18    GG           500
    4    19    TA           900
    5    NA    TT            NA
    6    NA    AG            NA
    

    【讨论】:

    • 谢谢安德烈!不幸的是,我不知道我必须提到患者数据集中有几个“探针”(请参阅​​问题中的编辑)。据我所知,merge() 不适用于这种情况,对吧?
    【解决方案2】:

    安装reshape2 包并尝试以下操作:

    require(reshape2)
    m.patients = melt(patients)
    m.patients = merge(m.patients, mlpa, 
                       by.x = "value", 
                       by.y = "probe", 
                       all = TRUE)
    reshape(m.patients, direction="wide", 
            timevar="variable", idvar="patid")
    

    这应该会为您提供如下输出,可以对其进行清理以匹配您想要的输出。

       patid value.probe1 probeposition.probe1 value.probe2 probeposition.probe2
    1     AT           12                  100           15                 1200
    2     GA           12                  100           15                 1200
    5     GG           18                  500           19                  900
    7     TA           19                  900           19                  900
    9     TT           NA                   NA           NA                   NA
    10    AG           NA                   NA           NA                   NA
    

    更新

    当然,您也可以使用reshape2 包完成所有操作,如下所示:

    m.patients = melt(patients, id.vars="patid", variable_name="time")
    m.patients = melt(merge(m.patients, mlpa, by.x = "value", 
                            by.y = "probe", all = TRUE))
    dcast(m.patients, patid ~ variable + time )
    

    结果:

      patid value_probe1 value_probe2 probeposition_probe1 probeposition_probe2
    1    AG           NA           NA                   NA                   NA
    2    AT           12           15                  100                 1200
    3    GA           12           15                  100                 1200
    4    GG           18           19                  500                  900
    5    TA           19           19                  900                  900
    

    更新 2:使用 Base R Reshape

    您也可以完全避免使用reshape2 包。

    patients.l = reshape(patients, direction="long", idvar="patid", 
                         varying=c("probe1", "probe2"), sep="")
    reshape(merge(patients.l, mlpa, all = TRUE), direction="wide", 
            idvar="patid", timevar="time")
    

    这会让你最接近你想要的输出:

       patid probe.1 probeposition.1 probe.2 probeposition.2
    1     AT      12             100      15            1200
    2     GA      12             100      15            1200
    5     GG      18             500      19             900
    7     TA      19             900      19             900
    9     TT      NA              NA      NA              NA
    10    AG      NA              NA      NA              NA
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多