这是关于R的效率的问题。我有两个具有names
属性的数值向量,我想基于公共names
有效地将一个向量的值分配给另一个向量。
例如,第一个向量定义为:
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
,第二个向量定义为:
b<-sample(letters, 5);
names(b)<-sample(1:10, 5);
b
9 10 6 5 1
"g" "j" "n" "u" "e"
现在,以下代码完全符合我的要求,它会查找与names(b)
相同的所有names(a)
,并在a
中为这些地点分配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"
我的问题是:有更好的方法吗??我正在处理更大的向量,我一直认为必须有更好的方法来做到这一点。
更复杂的方法,如:
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"
产生错误的结果,因为它要求首先排序names(b)
和names(a)
,这似乎也不是最佳策略。
任何想法都将不胜感激!
答案 0 :(得分:3)
正确的回答:
基于@flodel的评论
a[match(names(b), names(a))] <- b
老答案:
这很接近。它不保留a
的名称。我不知道为什么。您可以在事后重新分配a
的名称。
a <- b[match(names(a),names(b))]
答案 1 :(得分:3)
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"
答案 2 :(得分:1)
试试这个:
a[names(a) %in% names(b)] <- b[names(a[names(a) %in% names(b)])]
答案 3 :(得分:1)
我可能会这样做:
a[names(b)] <- b
> a
# 1 2 3 4 5 6 7 8 9 10
# "e" NA NA NA "u" "n" NA NA "g" "j"
如果b
不是a
的子集,例如:
set.seed(45)
a <- rep(NA, 10)
names(a) <- sample(10)
# 7 3 2 9 10 8 1 5 4 6
# NA NA NA NA NA NA NA NA NA NA
b <- sample(letters, 5)
names(b) <- sample(1:15, 5)
# 7 14 2 5 3
# "j" "w" "h" "k" "z"
len <- length(a)
a[names(b)] <- b
a[1:len]
# 7 3 2 9 10 8 1 5 4 6
# "j" "z" "h" NA NA NA NA "k" NA NA
答案 4 :(得分:0)
为您准备一条班轮:
a[as.integer(names(b))]<-b