使用重复的名称更改R向量中的多个元素

时间:2017-08-22 14:32:47

标签: r names

让我们说我有一个重复名字的向量:

x <- c(a=1, b=2, a=3, c=4, c=5, b=1, d=1)

我想查找和更改命名元素。如果我定义

ElementsToChange <- c("a","b","c")

ChangeTo <- c(9,8,7)

我想更改名为&#39; a&#39;的所有元素。所有那些名为&#39; b&#39;如果我这样做到8等等:

x[ElementsToChange] <- ChangeTo

这只会改变第一个(而不是全部)元素。

如何以简单而优雅的方式改变所有内容?

6 个答案:

答案 0 :(得分:10)

您可以使用单个split *命令执行此操作:

split(x, names(x))[ElementsToChange] <- ChangeTo
#x
#a b a c c b d 
#9 8 9 7 7 8 1 

首先按名称对x向量进行拆分,然后将属于ElementsToChange向量的所有元素子集化,并用ChangeTo值替换这些值。

*从技术上讲,您在这里使用split<-,即分配数据。原始矢量后来保持其结构。

答案 1 :(得分:4)

我认为你不需要保留任何匹配,这会使它不那么优雅:

ifelse(names(x)%in%ElementsToChange,ChangeTo[match(names(x),ElementsToChange)],x)
[1] 9 8 9 7 7 8 1

如果您想要返回名称,则必须重命名该矢量。

答案 2 :(得分:3)

当名称唯一时,命名元素的效果会更好,但您可以执行类似

的操作
Reduce(function(x, z) {
  x[names(x)==z$k] <- z$v
  x
}, split(data.frame(k=ElementsToChange, v=ChangeTo), seq_along(ChangeTo)), init=x)
# a b a c c b d 
# 9 8 9 7 7 8 1

但实际上,在data.frame中使用正确的键/值会更容易。

library(tidyverse)
dd <- data_frame(k=names(x), v=x)
tt <- data_frame(k=ElementsToChange, newv=ChangeTo)
dd %>% left_join(tt) %>% mutate(v=coalesce(newv, v), newv=NULL)

答案 3 :(得分:3)

直接替换为<-的另一个选项,归功于@Frank:

m <- match(names(x), ElementsToChange)
x[!is.na(m)] <- ChangeTo[na.omit(m)]

x
a b a c c b d 
9 8 9 7 7 8 1 

由于它直接替换它,它也保留了名称。您将x仅分组到ElementsToChange中的名称,然后将其值替换为ChangeTo

中的匹配元素

答案 4 :(得分:2)

ids = match(names(x), ElementsToChange)
replace(x, which(!is.na(ids)), ChangeTo[ids[!is.na(ids)]])
#a b a c c b d 
#9 8 9 7 7 8 1 

答案 5 :(得分:0)

您可以使用此功能并提供您的elementsToChange和changeTo向量以获取更改的列表。

declare @master table (id int, NameColumn varchar(64), BitFlag int)
insert into @master
values
(1,'Appl1',1),
(2,'Appl2',2),
(3,'Appl3',4),
(4,'Appl4',8)

declare @child table (TextColumn varchar(64), IdColumn varchar(64))
insert into @child
values
('SameText',1),
('SameText',2),
('OtherText',3)

select
    c.TextColumn
    ,BitFlag = sum(m.BitFlag)
from
    @child c
    inner join
        @master m on
        m.ID = c.IdColumn
group by
    c.TextColumn