R:从字典查找中检索值

时间:2014-10-15 01:02:57

标签: r lookup lookup-tables

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

                                     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函数,但这似乎也没有做到。

有什么想法吗?

感谢。

4 个答案:

答案 0 :(得分:1)

以下是众多方式之一:

读入数据:

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

答案 1 :(得分:1)

以下代码将合并到查找值中。将表格熔化为长格式允许我们通过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

答案 2 :(得分: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

答案 3 :(得分:1)

好吧,有人会提出一个更聪明的答案,但在这种情况下,我通常会采用自己的功能。假设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
}

然后你可以结果:

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