【问题标题】:Rename vector with conditions使用条件重命名向量
【发布时间】:2015-01-17 17:46:52
【问题描述】:

有一个向量看起来像这样

v <- c(2,5,8,5,6,6,6,6,6,6,4,3,35,7)

有没有办法可以把这些关卡变成

A,A1,A1,A1,A1,A1,A1,A1,A1,A1,A1,A1,A2,A1

我知道我可以使用 if(v &lt; 2){out &lt;- 'A'}if(v &lt; 10){out &lt;- 'A1'}if(v &gt; 10){out &lt;- 'A2'} 等 if 命令

但这非常慢,因为我的向量有近一百万个数字。有没有办法真正快速地做到这一点?理想情况下,我可以设置一个变量,其中包含应替换 A 的所有数字、应替换 A1 的 var,等等。

【问题讨论】:

  • 我觉得这个确切的问题是asked five times a day。这是某种新的 Coursera 作业吗?
  • Coursera 绝对是back in session
  • 你为什么不编辑你的问题?您还应该接受解决方案(关于您之前的所有问题,您从未接受过解决方案,也许您应该阅读 SO 是如何工作的)。这里的人尝试帮助你(例如 Akrun 给你至少 3 个解决方案),但至少要提出一个明确的问题并接受一个满足你要求的解决方案。

标签: r


【解决方案1】:

你可以试试cut

as.character(cut(v, breaks=c(0,2,10,Inf),
                labels=c('A', 'A1', 'A2')))
#[1] "A"  "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A2" "A1"

或者findInterval(这样会更快)

 c('A', 'A1', 'A2')[findInterval(v, c(0,2.1, 10, Inf))]

更新

如果要替换的值不遵循任何特定模式并且是根据您自己设定的规则决定的,则从“v”创建一个唯一值向量,并根据您需要替换的值命名它,并且使用[ 更快地替换整个向量。

unname(setNames( c('A', 'A1', 'A1', 'A1', 'A1', 'A1', 'A2', 'A1'),
   unique(v))[as.character(v)])
#[1] "A"  "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A2" "A1"

更新2

根据 OP 对 @agstudy 帖子的 cmets,如果要替换的值存储在几个向量中,则可能的 data.table 解决方案如下。假设与“v”匹配的“q”向量中的对应值应替换为“A”,“w”中的对应值应替换为“A1”,其余值为“A2”。在这里,我在“v”列表上使用setDT 创建了一个data.table,并使用“A2”预设了一个向量“V2”。将“V1”列设置为键(setkey),加入“q”,将对应的“V2”值分配为“A”,同样为“w”。

q <- c(3,7,6,9,8)
w <- c(4,14)
library(data.table)
setkey(setDT(list(v, V2=rep('A2', length(v)))), 
            V1)[J(q), V2:='A'][J(w), V2:='A1']$V2
 #[1] "A2" "A"  "A1" "A2" "A2" "A"  "A"  "A"  "A"  "A"  "A"  "A"  "A"  "A2"

【讨论】:

  • 问题是在数据中没有像这里那样的限制......它可以是0-8是A,然后9是A1,10又是A。这就是为什么我想为与 A、A1 等相关联的所有值设置一个变量......
  • @wery 那么也许你需要根据这些值重新编码。
  • 不太明白你的意思可以举个例子吗?
  • 我真的在寻找可以做类似事情的东西:如果向量的元素 i 是 2,8,9,7,6 然后用 A1 替换;如果它是 10,3 或 100 替换为 A2...但只是没有 1liner 或其他东西中的 if 语句..
  • 您的解决方案依赖于从 1 到 10 仅从 11 到...A2 以及更远...
【解决方案2】:

使用矢量化ifelse,这应该更快(至少对于给定的示例):

ifelse(v < 2 ,'A',ifelse(v < 10, 'A1', 'A2'))
[1] "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A1" "A2" "A1"

更一般地说(在 cmets 之后):

ifelse(v %in% vA ,'A',ifelse(v %in% vA1, 'A1', 'A2'))

其中vAvA1是一些向量,例如:

vA <- c(3,7,6,9,8)
vA1 <- c(4)

【讨论】:

  • 根据我帖子的 cmets,A 可以替换 10
  • 有没有可能说如果向量中的数字是 3,7,6,9,8(存储为 var(称为 q)那么它应该替换 A:如果是4 和 14 它应该将它存储为 A1(其中 4 和 14 存储在 w 中)像这样!!!
  • @Wery 我编辑了我的答案,但请编辑您的问题以准确说明这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-08
  • 1970-01-01
  • 2015-11-26
  • 2017-10-26
  • 1970-01-01
  • 2022-11-19
  • 1970-01-01
相关资源
最近更新 更多