0

假设我有一对因子,X 和 Y。此外,X 有三个水平,Y 有 4 个水平。一个例子可能是:

X = c("red","blue","yellow")
Y = c(1,2,3,4)

这显然是 12 种因素组合,假设对于每种组合,我想创建和存储一些数据,也许是作为数据框,或者作为像样条曲线这样的插值函数。关键是数据可能是任意的。

现在,我希望能够通过使用因素的组合来查找数据。我不知道这是否是正确的方法(因此我的问题),但我认为我可以解决这个问题:

dict <- list()
combinations <- expand.grid(X = c("red","blue","yellow"),Y = c(1,2,3,4))
for (i in 1:dim(combinations)[1]) {
  dict[paste(combinations$X[i],combinations$Y[i],sep=":")] <- paste(combinations$X[i],combinations$Y[i],sep=":")
}

结果:

> dict
$`red:1`
[1] "red:1"

$`blue:1`
[1] "blue:1"

$`yellow:1`
[1] "yellow:1"

$`red:2`
[1] "red:2"

$`blue:2`
[1] "blue:2"

$`yellow:2`
[1] "yellow:2"

$`red:3`
[1] "red:3"

$`blue:3`
[1] "blue:3"

$`yellow:3`
[1] "yellow:3"

$`red:4`
[1] "red:4"

$`blue:4`
[1] "blue:4"

$`yellow:4`
[1] "yellow:4"

现在,如果我想更改特定的键、值组合,我可以相对轻松地做到这一点:

dict["red:4"] <- "insert some cool function here"

> dict["red:4"]
$`red:4`
[1] "insert some cool function here"

因此,显然,如果您只是将文本作为值,这将非常愚蠢。但我认为如果“值”实际上是对象或数据框,它就会变得有用。大家对此怎么看?是否有另一种更简单的方法来实现我不知道的 R 中已经存在的相同类型的功能?

4

2 回答 2

2

您的 dict 的问题在于它实际上是一个列表,查找将是线性的,并且不会接近实际哈希表的性能。R 环境本身使用散列存储对象,因此您可以创建一个新环境,并将散列属性设置为TRUE像使用散列/字典一样使用它:

hash <- function( ) {
    return( new.env( hash = TRUE, parent = emptyenv() ) )
}

set <- function( hash, key, val ) {
    assign(key, val, envir = hash)
}

lookup <- function( hash, key) {
    return( get(key, envir = hash) )
}

d = hash()

set(d, 'a', 3)

print(lookup(d, 'a'))
## [1] 3

这是一个很好的资源,更详细地解释了这一点:http: //broadcast.oreilly.com/2010/03/lookup-performance-in-r.html

于 2013-05-28T01:55:17.600 回答
0

只是想我会添加一个矢量化版本 qwwqwwq 的答案。

hash <- function( ) {
  new.env( hash = TRUE, parent = emptyenv() ) 
}

set <- function(key, val, hash) {
  invisible(mapply(assign, key, val, MoreArgs = list(envir = hash)))
}

lookup <- function(key, hash, use_names = TRUE) {
  sapply(key, get, envir = hash, USE.NAMES = use_names)
}

然后您可以按如下方式使用...

> d = hash()
> set(letters, 1:26, d)
> lookup('z', d)
 z 
26 
> lookup('y', d)
 y 
25 
> lookup(c('x','y','z'), d)
 x  y  z 
24 25 26 
> lookup(c('x','y','z'), d, FALSE)
[1] 24 25 26
于 2015-08-25T10:17:11.577 回答