【问题标题】:R: Retrieve Values from Dictionary LookupR:从字典查找中检索值
【发布时间】:2023-03-17 16:40:02
【问题描述】:

所以我有一个如下所示的查找表:

                                     Round.Avg.Pos.
Keyword            1         2          3           4           5
   a          3.9524896 3.9524896 3.95248959 3.952489589 3.952489589
   b          0.5280526 0.5280526 0.52805261 0.528052609 0.528052609
   c          3.9524896 3.9524896 3.95248959 3.952489589 3.952489589
   d          1.2957861 1.3829949 1.16840983 1.022428296 0.955781037
   e          2.5253513 0.3581801 0.05080204 0.007205446 0.0010219761

我有一个像这样的数据框:

Keyword     Round.Avg.Pos.
a                 1
a                 2
a                 4
b                 3 
b                 5 
c                 2
c                 3   
d                 1
e                 1
e                 3 
e                 5

我需要在数据框中添加另一列,其中包含从查找表中检索到的数字,使其看起来像这样:

Keyword     Round.Avg.Pos.     Ratio
a                 1          3.9524896
a                 2          3.9524896 
a                 4          3.9524896 
b                 3          0.52805261
b                 5          0.528052609
c                 2          3.9524896 
c                 3          3.9524896 
d                 1          1.2957861 
e                 1          2.5253513 
e                 3          0.05080204 
e                 5          0.0010219761

我尝试使用子集技术,它适用于一行,但我无法让它同时适用于整个数据框。我还尝试了 qdapTools 包中的 LOOKUP 功能,但这似乎也不正确。

有什么想法吗?

谢谢。

【问题讨论】:

    标签: r dataframe lookup lookup-tables


    【解决方案1】:

    这可能是你想要的:

    mat <- matrix(1:50, ncol=5)
    rownames(mat) <- letters[1:10]
    colnames(mat) <- 1:5
    mat
       1  2  3  4  5
    a  1 11 21 31 41
    b  2 12 22 32 42
    c  3 13 23 33 43
    d  4 14 24 34 44
    e  5 15 25 35 45
    f  6 16 26 36 46
    g  7 17 27 37 47
    h  8 18 28 38 48
    i  9 19 29 39 49
    j 10 20 30 40 50
    df <- cbind(sample(letters[1:10], replace=TRUE), sample(5, replace=TRUE))
    df
          [,1] [,2]
     [1,] "f"  "4" 
     [2,] "b"  "1" 
     [3,] "h"  "3" 
     [4,] "e"  "5" 
     [5,] "f"  "2" 
     [6,] "b"  "4" 
     [7,] "d"  "1" 
     [8,] "j"  "3" 
     [9,] "e"  "5" 
    [10,] "h"  "2" 
    
    i <- match(df[,2], colnames(mat))
    j <- match(df[,1], rownames(mat))
    inds <- (i-1) * nrow(mat) + j
    mat[inds]
      [1] 36  2 28 45 16 32  4 30 45 18
    

    【讨论】:

    • 看到了吗?我知道一个更聪明的答案即将到来。比我更吝啬。
    【解决方案2】:

    好吧,有人会想出一个更聪明的答案,但在这种情况下,我通常会求助于编写自己的函数。假设 df1 是您的查找表,而 df2 是您拥有的第二个表,则可以像这样查找您的值:

    lookup <- function(df1, df2) {
        res = numeric(); # empty vector for our results
        for(i in 1:nrow(df2)) {
            ix <- which(df[,1] == df2[i,1]); # lookup the row
            res <- c(res, df[ix, df2[i,2]+1]) # add 1 because first column is labels
        }
        res
    }
    

    然后就可以cbind结果了:

    final = cbind(df2, lookup(df1, df2))
    

    【讨论】:

      【解决方案3】:

      以下代码将合并查找值。将表格融合为长格式允许我们通过KeywordRound.Avg.Pos. 的值将表格合并到数据框中。假设您的表名为tab,而您的数据框名为dat

      library(reshape2)
      
      # Melt the table into long format
      tab.m = melt(tab, id.var="Keyword", variable.name="Round.Avg.Pos.")
      
      # melt converts "Round.Avg.Pos." to a factor, so turn it back into numeric
      tab.m$Round.Avg.Pos. = as.numeric(as.character(tab.m$Round.Avg.Pos.))
      
      # Merge in table values
      dat.merged = merge(dat, tab.m, by=c("Keyword","Round.Avg.Pos."), all.x=TRUE)
      
      dat.merged
         Keyword Round.Avg.Pos.       value
      1        a              1 3.952489600
      2        a              2 3.952489600
      3        a              4 3.952489589
      4        b              3 0.528052610
      5        b              5 0.528052609
      6        c              2 3.952489600
      7        c              3 3.952489590
      8        d              1 1.295786100
      9        e              1 2.525351300
      10       e              3 0.050802040
      11       e              5 0.001021976
      

      【讨论】:

        【解决方案4】:

        这里有很多方法之一:

        读入数据:

        key <- read.table(text="Keyword            1         2          3           4           5
           a          3.9524896 3.9524896 3.95248959 3.952489589 3.952489589
           b          0.5280526 0.5280526 0.52805261 0.528052609 0.528052609
           c          3.9524896 3.9524896 3.95248959 3.952489589 3.952489589
           d          1.2957861 1.3829949 1.16840983 1.022428296 0.955781037
           e          2.5253513 0.3581801 0.05080204 0.007205446 0.0010219761", header=TRUE, check.names=FALSE)
        
        dat <- read.table(text="Keyword     Round.Avg.Pos.
        a                 1
        a                 2
        a                 4
        b                 3 
        b                 5 
        c                 2
        c                 3   
        d                 1
        e                 1
        e                 3 
        e                 5", header=TRUE)
        

        方法:

        我确信data.table 和/或dplyr 也有非常棒的快速方法。这是一种不起眼的索引方法。

        如果你想使用qdap 框架,这里的方法是:

        library(reshape2)
        library(qdap)
        mkey <- melt(key)
        mkey <- colpaste2df(mkey, 1:2, keep.orig = FALSE)
        dat[["Ratio"]] <- paste2(dat) %l% mkey[, 2:1]
        dat
        

        关键字 Round.Avg.Pos.比率

        ## 1        a              1 3.952489600
        ## 2        a              2 3.952489600
        ## 3        a              4 3.952489589
        ## 4        b              3 0.528052610
        ## 5        b              5 0.528052609
        ## 6        c              2 3.952489600
        ## 7        c              3 3.952489590
        ## 8        d              1 1.295786100
        ## 9        e              1 2.525351300
        ## 10       e              3 0.050802040
        ## 11       e              5 0.001021976
        

        【讨论】:

          猜你喜欢
          • 2019-10-12
          • 2023-02-08
          • 1970-01-01
          • 2011-06-30
          • 2021-02-27
          • 2019-11-26
          • 1970-01-01
          • 2013-10-23
          • 2018-06-09
          相关资源
          最近更新 更多