Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

match names between vectors and assign corresponding values

Tags:

r

This is a problem about efficiency in R. I have two numerical vectors with names attributes, and I want to efficiently assign the values of one vector to the other based on the common names.

For example, the first vector is defined as:

set.seed(1);
a<-rep(NA,10);
names(a)<-1:10;
d<-a;  #  we will need this later 
a

 1  2  3  4  5  6  7  8  9 10 
NA NA NA NA NA NA NA NA NA NA

and the second vector is defined as:

b<-sample(letters, 5);
names(b)<-sample(1:10, 5);
b

9  10   6   5   1 
"g" "j" "n" "u" "e" 

now the following code does exactly what I want, it looks for all names(b) that are common with names(a) and assigns to those places in a the values of b:

for(p in 1:length(b)){
    a[which(names(a) == names(b)[p])]<-b[p]
};

a

1   2   3   4   5   6   7   8   9  10 
"e"  NA  NA  NA "u" "n"  NA  NA "g" "j" 

My question is: is there a better more efficient way of doing this? I am dealing with much larger vectors and I keep thinking that there must be a better way of doing this.

A more sophisticated method like:

d[which(names(d) %in% names(b))]<- b
d

1   2   3   4   5   6   7   8   9  10 
"g"  NA  NA  NA "j" "n"  NA  NA "u" "e"  

all.equal(a,d)

[1] "4 string mismatches"

produces wrong results because it requires that names(b) and names(a) are ordered first, which also does not seem to be an optimal strategy.

Any ideas would be greatly appreciated!

like image 263
fkliron Avatar asked Oct 19 '25 19:10

fkliron


2 Answers

a[intersect(names(b), names(a))] <- b[intersect(names(b), names(a))]
> a
  1   2   3   4   5   6   7   8   9  10 
"e"  NA  NA  NA "u" "n"  NA  NA "g" "j" 
like image 94
user1609452 Avatar answered Oct 22 '25 10:10

user1609452


CORRECT ANSWER:

Based on a comment from @flodel

a[match(names(b), names(a))] <- b

OLD ANSWER:

This gets close. It does not preserve the names of a. I am not sure why. You could reassign the names of a after the fact.

a <- b[match(names(a),names(b))]
like image 29
dayne Avatar answered Oct 22 '25 08:10

dayne



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!