Reputation: 2977
This actually corresponds to my other question but things get more complicated. I have data.frame and vector:
df <- data.frame(key=c(0,3:6), value=c(0,52,26,12,1))
x <- c(3,4,3,3,5,5,6,6,6,6)
and need to obtain values from df based on x as keys:
[1] 52 26 52 52 12 12 1 1 1 1
Solution from previous answer can only give result with NO duplicates:
df[df$key %in% x,"value"]
[1] 52 26 12 1
Is there a way to solve this?
Also, I see hash() can do things like:
h <- hash( keys=letters, values=1:26 )
h$a # 1
h[ "a" ]
h[[ "a" ]]
z <- rep(letters[3:5],2)
h[z] # still with NO duplicates
<hash> containing 3 key-value pair(s).
c : 3
d : 4
e : 5
But seems like it cannot return a vector of values with something like:
h[[z]]
Error in h[[z]] : wrong arguments for subsetting an environment
Otherwise, it would be perfect so that we can get rid of data.frame by using some 'real' hash concept.
Thanks!
Upvotes: 5
Views: 3321
Reputation: 3623
I'm not sure if this is the best way, but merge()
will get you there:
df <- data.frame(key=c(0,3:6), value=c(0,52,26,12,1))
x <- c(3,4,3,3,5,5,6,6,6,6)
merge(x, df, by.x="x", by.y = "key")
# x value
# 1 3 52
# 2 3 52
# 3 3 52
# 4 4 26
# 5 5 12
# 6 5 12
# 7 6 1
# 8 6 1
# 9 6 1
Update
Regarding your question on hash()
, would something like the following do for now?
hashMatch <- function(x, y)
{
laply(y, function(z)
{
x[[z]]
})
}
require(plyr)
require(hash)
h <- hash( keys=letters, values=1:26 )
z <- rep(letters[3:5],2)
hashMatch(h, z)
# [1] 3 4 5 3 4 5
Upvotes: 2
Reputation: 179558
To answer your first question: Use match
df[match(x, df$key), ]
key value
2 3 52
3 4 26
2.1 3 52
2.2 3 52
4 5 12
4.1 5 12
5 6 1
5.1 6 1
5.2 6 1
5.3 6 1
You should also have a look at Named vectors
dat <- c(0,52,26,12,1)
names(dat) <- as.character(c(0,3:6))
dat[as.character(x)]
3 4 3 3 5 5 6 6 6 6
52 26 52 52 12 12 1 1 1 1
Upvotes: 3
Reputation: 66874
You can use match
to select your values:
df[match(x,df$key),"value"]
[1] 52 26 52 52 12 12 1 1 1 1
Upvotes: 2