让我们说我有一个重复名字的向量:
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
这只会改变第一个(而不是全部)元素。
如何以简单而优雅的方式改变所有内容?
答案 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