将向量的每个元素与 R 中的另一个向量组合
Posted
技术标签:
【中文标题】将向量的每个元素与 R 中的另一个向量组合【英文标题】:Combine each element of a vector with another vector in R 【发布时间】:2015-06-29 22:23:48 【问题描述】:我有两个向量
x <- c(2, 3, 4)
y <- rep(0, 5)
我想得到以下输出:
> z
2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0
如何创建z
?我曾尝试使用paste
和c
,但似乎没有任何效果。我唯一能想到的是使用for()
,它非常慢。我用谷歌搜索了这个,我确信解决方案就在那里,我只是没有找到正确的关键字。
更新: 用于基准测试:
使用 Nicola 的解决方案:
> system.time(
+ precipitation <- `[<-`(numeric(length(x)*(length(y)+1)),seq(1,by=length(y)+1,length.out=length(x)),x)
+ )
user system elapsed
0.419 0.407 0.827
这速度快得离谱!我必须说!有人可以向我解释一下吗?我的for()
我知道在R
中总是错误的,如果它完成的话,至少需要一天时间。
其他建议:
> length(prate)
[1] 4914594
> length(empty)
[1] 207
> system.time(
+ precipitation <- unlist(sapply(prate, FUN = function(prate) c(prate,empty), simplify=FALSE))
+ )
user system elapsed
16.470 3.859 28.904
我不得不杀了
len <- length(prate)
precip2 <- c(rbind(prate, matrix(rep(empty, len), ncol = len)))
15 分钟后。
【问题讨论】:
虽然没有@nicola那么快,但另一个选择是rep(x, each=length(y)+1)*c(1,y)
当y
由全零组成时,我进行了编辑以加快处理速度。
【参考方案1】:
由于某种原因,这似乎更快:
unlist(t(matrix(c(as.list(x),rep(list(y),length(x))),ncol=2)))
上述解决方案是通用的,因为x
和y
都可以具有任何值。在 OP 的情况下,y
仅由 0 组成,这很快:
`[<-`(numeric(length(x)*(length(y)+1)),seq(1,by=length(y)+1,length.out=length(x)),x)
#[1] 2 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0
编辑
我意识到我一直很神秘,我编写的代码并不容易理解,尽管只有一行。我将详细解释第二种解决方案的作用。
首先,您注意到生成的向量将包含x
中包含的值加上y
中的零重复length(x)
次。所以总的来说,它将是length(x) + length(x)*length(y)
或length(x)*(length(y)+1)
long。所以我们根据需要创建一个只有零的向量:
res<-numeric(length(x)*(length(y)+1))
现在我们必须将x
值放入res
。我们注意到x
的第一个值占据了res
的第一个值;第二个将在第一个之后的length(y)+1
之后,依此类推,直到填充所有length(x)
值。我们可以创建一个索引向量,将x
值放入其中:
indices<-seq.int(1,by=length(y)+1,length.out=length(x))
然后我们进行替换:
res[indices]<-x
我的行只是上面三行的捷径。希望这能澄清一点。
【讨论】:
您的解决方案是迄今为止最快的。我认为t
可能会降低速度,但它没有
是的,有趣的解决方案。
非常好的解决方案。您可以使用integer
而不是numeric
以使其更快。
另外seq.int
而不是seq
似乎更快。 ;)
nicola 的解决方案基本上是x=1:1e5;y=rep(0,40);tmp=numeric(length(x)*(length(y)+1));tmp[seq(1,by=length(y)+1,length.out=length(x))]=x;
的简写。比较:all.equal([<-
(numeric(length(x)*(length(y)+1)),seq(1,by=length(y)+1,length.out=length(x )),x),tmp)
【参考方案2】:
你可以试试这个
unlist(sapply(x, FUN = function(x) c(x,y), simplify=FALSE))
[1] 2 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0
或更简单的@docendodiscimus
unlist(lapply(x, FUN = function(x) c(x,y)))
【讨论】:
你可以使用lapply
所以你不需要指定simplify = FALSE
我没有尝试其他建议,但这非常快(大约需要 30 秒,而我的循环至少需要一天)。
@cddesjardins 如果您也测试其他答案的速度会很有趣。
并且可以在调用中添加 y,因此它不依赖 y 作为第二个向量的名称,从而导致: unlist (lapply(x, function(x, y) c(x ,y), y))【参考方案3】:
你也可以尝试如下矢量化
len <- length(x)
c(rbind(x, matrix(rep(y, len), ncol = len)))
## [1] 2 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0
一个更紧凑但可能更慢的选项(由@akrun 提供)是
c(rbind(x, replicate(len, y)))
## [1] 2 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0
【讨论】:
在 1e6 'x' 向量和长度为 100 的 'y' 上尝试了一些基准测试。使用dim<-
更快一点,@Mamoun Benghezal 的解决方案首先出现,replicate
解决方案是最慢的,但比例为 1 与 2.9
@akrun 有趣。虽然很奇怪【参考方案4】:
你可以试试:
c(sapply(x, 'c', y))
#[1] 2 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0
或者使用 gusb 和粘贴的疯狂解决方案..
library(functional)
p = Curry(paste0, collapse='')
as.numeric(strsplit(p(gsub('(.*)$', paste0('\\1',p(y)),x)),'')[[1]])
#[1] 2 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0
【讨论】:
【参考方案5】:这是另一种方式:
options(scipen=100)
as.numeric(unlist(strsplit(as.character(x * 10^5), "")))
还有一些基准测试:
microbenchmark(as.numeric(unlist(strsplit(as.character(x*10^5), ""))), unlist(t(matrix(c(as.list(x),rep(list(y),length(x))),ncol=2))), unlist(sapply(x, FUN = function(x) c(x,y), simplify=FALSE)), times=100000)
Unit: microseconds
expr
as.numeric(unlist(strsplit(as.character(x * 10^5), "")))
unlist(t(matrix(c(as.list(x), rep(list(y), length(x))), ncol = 2)))
unlist(sapply(x, FUN = function(x) c(x, y), simplify = FALSE))
min lq mean median uq max neval
9.286 10.644 12.15242 11.678 12.286 1650.133 100000
9.485 11.164 13.25424 12.288 13.067 1887.761 100000
5.607 7.429 9.21015 8.147 8.784 30457.994 100000
这是另一个想法(但似乎很慢):
r = rle(1)
r$lengths = rep(c(1,5), length(x))
r$values = as.vector(rbind(x, 0))
inverse.rle(r)
【讨论】:
基于 OP 帖子中的x
,我得到as.numeric(unlist(strsplit(as.character(x * 10^5), ""))) #[1] 2 NA NA 0 5 3 NA NA 0 5 4 NA NA 0 5
,这不是预期的结果
搞笑,我猜对了:as.numeric(unlist(strsplit(as.character(x * 10^5), ""))) [1] 2 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 0
@akrun 哦耶——关闭科学记数法:options(scipen=100)
以上是关于将向量的每个元素与 R 中的另一个向量组合的主要内容,如果未能解决你的问题,请参考以下文章