【问题标题】:Combining two vectors element-by-element逐个元素组合两个向量
【发布时间】:2012-09-20 11:14:53
【问题描述】:

我有 2 个向量,例如:

A <- c(1,2,NA,NA,NA,NA,7)
B <- c(NA,NA,3,4,NA,NA,7)

我想将它们组合起来,这样得到的向量就是

1,2,3,4,NA,NA,-1

那是

  1. 当位置 i 的任一向量中仅存在 1 个值(例如 X)时(另一个为 NA),新向量应取位置 i 处的值 X。

  2. 当两个值在位置 i 处均为 NA 时,新向量应在位置 i 处取值 NA

  3. 当两个向量在位置 i 处都有值时,新向量应在位置 i 处取值 -1。

我可以通过循环轻松完成此操作,但在大型数据集上速度很慢,因此任何人都可以提供一种快速的方法来执行此操作吗?

【问题讨论】:

  • 迭代似乎是你唯一的希望。缓慢可能是因为分支预测问题。
  • 您认为大型数据集是什么?

标签: r


【解决方案1】:

这些命令创建向量:

X <- A
X[is.na(A)] <- B[is.na(A)]
X[is.na(B)] <- A[is.na(B)]
X[!is.na(A & B)] <- -1

#[1]  1  2  3  4 NA NA -1

【讨论】:

  • 这就是我要说的……我得早点起床!
  • 如果你一开始就用X &lt;- -A^0来创建一个带-1的向量,你就不需要最后一行了,整个事情会更快。
  • 有趣,@Roland:原来X &lt;- -A^0X&lt;- rep(-1,length(A)) 快​​
  • @Carl Witthoft 是的,如果您需要优化代码,这是一个方便的技巧。
【解决方案2】:
A <- c(1,2,NA,NA,NA,NA,7)
B <- c(NA,NA,3,4,NA,NA,7)
C <- rowMeans(cbind(A,B),na.rm=TRUE)
C[which(!is.na(A*B))]<- -1
#[1]   1   2   3   4 NaN NaN  -1

基准测试:

Unit: microseconds
          expr    min     lq median     uq     max
1 Roland(A, B) 17.863 19.095 19.710 20.019  68.985
2   Sven(A, B) 11.703 13.243 14.167 14.783 100.398

【讨论】:

  • 除了 NaN 和 NA 不一样。您应该添加一行以将 NaN 替换为 NA
  • 如果这很重要,很容易做到。但是,无论如何,Sven 的解决方案效率更高。
  • 此解决方案的一个优点是,如果存在两个值,它会提供平均值。这在某些情况下可能很有用。
【解决方案3】:

聚会有点晚了,但这里有另一个选项定义一个函数,该函数通过将规则应用于两个向量cbind-ed 一起工作。

# get the data
A <- c(1,2,NA,NA,NA,NA,7)
B <- c(NA,NA,3,4,NA,NA,7)

# define the function
process <- function(A,B) {
  x <- cbind(A,B)
  apply(x,1,function(x) {
    if(sum(is.na(x))==1) {na.omit(x)} else
    if(all(is.na(x))) {NA} else
    if(!any(is.na(x))) {-1}
  })
}

# call the function
process(A,B)
#[1]  1  2  3  4 NA NA -1

使用函数的主要好处是更容易更新规则或输入以将代码应用于新数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多