将向量的每个元素与R

时间:2015-04-22 10:23:01

标签: r vector combinations

我有两个载体

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?我曾尝试使用pastec但似乎没有任何效果。我唯一能想到的就是使用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)))

我不得不杀了

<?php

class ViewHelpers {

    public static function bah()
    {
        echo 'blah';
    }
}
15分钟后。

5 个答案:

答案 0 :(得分:5)

由于某种原因,这似乎更快:

 unlist(t(matrix(c(as.list(x),rep(list(y),length(x))),ncol=2)))

上述解决方案是通用的,因为xy都可以具有任何价值。在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)长。因此,只要需要,我们就会创建一个只有零的向量:

  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

我的专栏只是上面三行的捷径。希望这澄清一点。

答案 1 :(得分:4)

你可以试试这个

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)))

答案 2 :(得分:2)

你也可以尝试按照以下方式进行矢量化

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

答案 3 :(得分:1)

您可以尝试:

 c(sapply(x, 'c', y))
 #[1] 2 0 0 0 0 0 3 0 0 0 0 0 4 0 0 0 0 

或者使用gusb和paste的疯狂解决方案..

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

答案 4 :(得分:1)

这是另一种方式:

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)