【问题标题】:How to match 2 dataframe columns and extract column values and column names?如何匹配 2 个数据框列并提取列值和列名?
【发布时间】:2015-12-22 08:27:23
【问题描述】:

我有一个名为mymat 的矩阵。我有一个名为geno <- c("01","N1","11","1N","10") 的向量。我还有另一张桌子叫key.table。我想要做的是我想将key.table 中的key 列与mymat 中的key 列匹配,并且如果任何匹配行中的列值具有任何geno 元素,我想从mymat 中提取该列名以及匹配的geno 元素,并将其粘贴到key.tablekey.table 中每个key 的相应行中的新列中,并获得结果。

  mymat <- structure(c("chr5:12111", "chr5:12111", "chr5:12113", "chr5:12114", 
"chr5:12118", "0N", "0N", "1N", "0N", "0N", "00", "00", "00", 
"11", "10", "00", "00", "1N", "0N", "00"), .Dim = c(5L, 4L), .Dimnames = list(
    c("34", "35", "36", "37", "38"), c("key", "AMLM12001KP", 
    "AMAS-11.3-Diagnostic", "AMLM12014N-R")))

key.table<- structure(c("chr5:12111", "chr5:12111", "chr5:12113", "chr5:12114", 
"chr5:12118", "chr5:12122", "chr5:12123", "chr5:12123", "chr5:12125", 
"chr5:12127", "chr5:12129", "9920068", "9920069", "9920070", 
"9920071", "9920072", "9920073", "9920074", "9920075", "9920076", 
"9920077", "9920078"), .Dim = c(11L, 2L), .Dimnames = list(c("34", 
"35", "36", "37", "38", "39", "40", "41", "42", "43", "44"), 
    c("key", "variantId")))

结果

  key          variantId    matched.extract
34 "chr5:12111" "9920068"     NA
35 "chr5:12111" "9920069"     NA
36 "chr5:12113" "9920070"     AMLM12001KP (1N),AMLM12014N-R (1N)
37 "chr5:12114" "9920071"     AMAS-11.3-Diagnostic (11)
38 "chr5:12118" "9920072"     AMAS-11.3-Diagnostic (10)
39 "chr5:12122" "9920073"     NA
40 "chr5:12123" "9920074"     NA
41 "chr5:12123" "9920075"     NA
42 "chr5:12125" "9920076"     NA
43 "chr5:12127" "9920077"     NA
44 "chr5:12129" "9920078"     NA

【问题讨论】:

  • 所以我们只对“1N”、“11”和“10”的值感兴趣?你不清楚。
  • @MikeWise 没错,我们只想在单元格具有这些值中的任何一个时才提取。

标签: r


【解决方案1】:

使用,我会这样处理:

library(data.table)
# convert the 'key.table' matrix to a data.table
kt <- as.data.table(key.table, keep.rownames=TRUE)
# convert the 'mymat' matrix to a data.table and melt into long format
# filter on the needed geno-types
# paste the needed values together into the requested format
mm <- melt(as.data.table(mymat, keep.rownames=TRUE),
           id=c("rn","key"))[value %in% c("1N","11","10"), val := paste0(variable," (",value,")")
                             ][, .(val = paste(val[!is.na(val)], collapse = ",")), by = .(rn,key)
                               ][val=="", val:=NA]
# join the 'mm' and 'kt' data.tables
kt[mm, matched := val, on=c("rn","key")]

给出:

> kt
    rn        key variantId                            matched
 1: 34 chr5:12111   9920068                                 NA
 2: 35 chr5:12111   9920069                                 NA
 3: 36 chr5:12113   9920070 AMLM12001KP (1N),AMLM12014N-R (1N)
 4: 37 chr5:12114   9920071          AMAS-11.3-Diagnostic (11)
 5: 38 chr5:12118   9920072          AMAS-11.3-Diagnostic (10)
 6: 39 chr5:12122   9920073                                 NA
 7: 40 chr5:12123   9920074                                 NA
 8: 41 chr5:12123   9920075                                 NA
 9: 42 chr5:12125   9920076                                 NA
10: 43 chr5:12127   9920077                                 NA
11: 44 chr5:12129   9920078                                 NA

解释

  • kt &lt;- as.data.table(key.table, keep.rownames=TRUE) 会将矩阵 key.table 转换为 data.table(这是增强的 data.frame)并将行名存储在 rn 列中。
  • mm &lt;- melt(as.data.table(mymat, keep.rownames=TRUE), id=c("rn","key")) 会将矩阵 mymat 转换为 data.table,将行名存储在 rn 列中,并将 data.table 融合为长格式。
  • [value %in% c("1N","11","10"), val := paste0(variable," (",value,")")] 部分将粘贴variable 值(它们是mymat 中的列名)和value 值,仅在value1N11 的情况下或10
  • [, .(val = paste(val[!is.na(val)], collapse = ",")), by = .(rn,key)] 部分将通过rnkey 变量将val 的非NA 行粘贴在一起。
  • [val=="", val:=NA] 部分会将val 的空行转换为NA-values
  • 最后,kt[mm, matched := val, on=c("rn","key")] 通过引用mm-data.table 的val-值来更新kt-data.table,以匹配rnkey 变量。

警告:在使用data.table时,最好不要将key作为变量名作为@使用987654356@ 也是data.table 中的一个参数。更多信息请参见?key

【讨论】:

  • 非常感谢,这正是我所需要的。
  • 请帮我了解一下你是如何在这里使用融化功能的。看起来很有趣,我真的很想了解它。您能否解释一下您是如何将valvaluespaste0(variable," (",value,")") 放在上下文中的?
  • @MAPK 添加了解释并改进了答案。 HTH
  • 谢谢,非常感谢。
【解决方案2】:

我对 dplyr 函数不是很熟悉。你可以试试base R的合并功能:

mm <- merge(key.table,mymat,by="key",all.x=T)
mm

使用组织类型粘贴列名的功能:

get.geno <- function(x,y) ifelse(!x %in% c("00","0N") & !is.na(x), paste0(y," (",x,")"), NA)
a <- t(apply(mm[,3:5], 1, get.geno, colnames(mm)[3:5]))

最终数据框:

mm$result <- apply(a, 1, function(x) paste(x[!is.na(x)] ,collapse=","))
mm[, -3:-5]
          key   variantId                           result
1  chr5:12111   9920068                                   
2  chr5:12111   9920068                                   
3  chr5:12111   9920069                                   
4  chr5:12111   9920069                                   
5  chr5:12113   9920070 AMLM12001KP (1N),AMLM12014N-R (1N)
6  chr5:12114   9920071          AMAS-11.3-Diagnostic (11)
7  chr5:12118   9920072          AMAS-11.3-Diagnostic (10)
8  chr5:12122   9920073                                   
9  chr5:12123   9920074                                   
10 chr5:12123   9920075                                   
11 chr5:12125   9920076                                   
12 chr5:12127   9920077                                   
13 chr5:12129   9920078    

【讨论】:

  • 那么它是什么样子的?
  • @MikeWise 谢谢,但您看到这一行36 "chr5:12113" "9920070" AMLM12001KP (1N),AMLM12014N-R (1N) 有多个列名。只有当键匹配的行在列中具有geno 值之一时,我们才对提取所有列名感兴趣。
  • 错误,不确定该评论是什么意思。
  • 善用merge+1
【解决方案3】:

不完全确定你想要什么,但它可能接近这个:

library(reshape2)
mymat <- structure(
  c("chr5:12111", "chr5:12111", "chr5:12113", "chr5:12114",
    "chr5:12118", "0N", "0N", "1N", "0N", "0N", "00", "00", "00", 
    "11", "10", "00", "00", "1N", "0N", "00"), .Dim = c(5L, 4L), 
  .Dimnames = list(
    c("34", "35", "36", "37", "38"), 
    c("key", "AMLM12001KP", "AMAS-11.3-Diagnostic", "AMLM12014N-R")))

key.table<- structure(
  c("chr5:12111", "chr5:12111", "chr5:12113", "chr5:12114", 
    "chr5:12118", "chr5:12122", "chr5:12123", "chr5:12123", "chr5:12125", 
    "chr5:12127", "chr5:12129", "9920068", "9920069", "9920070", 
    "9920071", "9920072", "9920073", "9920074", "9920075", "9920076", 
    "9920077", "9920078"), .Dim = c(11L, 2L), 
  .Dimnames = list(
    c("34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44"), 
                   c("key", "variantId")))

# work with dataframes
mmdf <- data.frame(mymat)
ktdf <- data.frame(key.table)

tdf <- merge(mmdf,ktdf,by="key")
mltdf <- melt(tdf,id.vars=c("key","variantId"))
mltdf1 <- mltdf[mltdf$value != "0N" & mltdf$value != "00" ,]

mltdf1

产量:

          key variantId             variable value
5  chr5:12113   9920070          AMLM12001KP    1N
13 chr5:12114   9920071 AMAS.11.3.Diagnostic    11
14 chr5:12118   9920072 AMAS.11.3.Diagnostic    10
19 chr5:12113   9920070         AMLM12014N.R    1N

【讨论】:

    猜你喜欢
    • 2020-09-29
    • 2016-02-03
    • 2018-10-01
    • 2022-11-13
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多