重复在向量中的元素与for循环

时间:2018-02-17 10:18:36

标签: r loops for-loop vector repeat

我想在R中从3:50制作一个矢量,看起来像

  

3 4 4 5 6 6 7 8 8 .. 50 50

我想在for循环中使用for循环,但它没有做我想要的wat。

f <- c()
for (i in 3:50) {
  for(j in 1:2) {
    f = c(f, i)
  }
}

它出了什么问题?

8 个答案:

答案 0 :(得分:16)

另一种选择是使用嵌入式rep

rep(3:50, rep(1:2, 24))

给出:

 [1]  3  4  4  5  6  6  7  8  8  9 10 10 11 12 12 13 14 14 15 16 16 17 18 18 19 20 20
[28] 21 22 22 23 24 24 25 26 26 27 28 28 29 30 30 31 32 32 33 34 34 35 36 36 37 38 38
[55] 39 40 40 41 42 42 43 44 44 45 46 46 47 48 48 49 50 50

这利用times - rep - s <- 3 e <- 50 v <- 1:2 rep(s:e, rep(v, (e-s+1)/2)) 参数也可以是一个整数向量,它等于x参数的长度。

您可以将其概括为:

rep

使用rep_lenv <- 3:50 rep(v, rep_len(1:2, length(v))) 混合的其他选项:

error_reporting(E_ALL & ~(E_STRICT|E_NOTICE|E_WARNING));

$host="localhost";
$dbuser="xcanberr_accountmanager";
$dbpass="*********”;
$dbname="xcanberr_PromoCodes";

$link = mysqli_connect($host, $dbuser, $dbpass,$dbname);
if(!$link){


    $bookingId = "XBR".date("dmYHis");

    $firstName          = mysqli_real_escape_string($link, $firstName);
    $email              = mysqli_real_escape_string($link, $email);
    $phone              = mysqli_real_escape_string($link, $phone);
    $pickupAddressLine1 = mysqli_real_escape_string($link, $pickupAddressLine1);
    $dropAddressLine1   = mysqli_real_escape_string($link, $dropAddressLine1);

    $sql = "INSERT INTO booking_table (bookingID, first_name, last_name, email, phone, pickup_location, drop_location)
    VALUES ('$bookingId', '$firstName', '$lastName', '$email', '$phone','$pickupAddressLine1', '$dropAddressLine1')";

    mysqli_query($link, $sql);

答案 1 :(得分:9)

基于sapply的解决方案。

as.vector(sapply(0:23 * 2 + 2, function(x)  x + c(1, 2, 2)))

# [1]  3  4  4  5  6  6  7  8  8  9 10 10 11 12 12 13 14 14 15 16 16 17 18 18 19 20 20 21 22 22 23 24 24 25 26 26
# [37] 27 28 28 29 30 30 31 32 32 33 34 34 35 36 36 37 38 38 39 40 40 41 42 42 43 44 44 45 46 46 47 48 48 49 50 50

<强>基准

以下是所有当前答案的效果比较。结果显示cumsum(rep(c(1, 1, 0), 24)) + 2Lm8)是最快的,而rep(3:50, rep(1:2, 24))m1)几乎与m8一样快。

library(microbenchmark)
library(ggplot2)

perf <- microbenchmark(
  m1 = {rep(3:50, rep(1:2, 24))},
  m2 = {rep(3:50, each = 2)[c(TRUE, FALSE, TRUE, TRUE)]},
  m3 = {v <- 3:50; sort(c(v,v[v %% 2 == 0]))},
  m4 = {as.vector(t(cbind(seq(3,49,2),seq(4,50,2),seq(4,50,2))))},
  m5 = {as.vector(sapply(0:23 * 2 + 2, function(x)  x + c(1, 2, 2)))},
  m6 = {sort(c(3:50, seq(4, 50, 2)))},
  m7 = {rep(seq(3, 50, 2), each=3) + c(0, 1, 1)},
  m8 = {cumsum(rep(c(1, 1, 0), 24)) + 2L},
  times = 10000L
)

perf
# Unit: nanoseconds
# expr   min    lq      mean median    uq     max neval
#   m1   514  1028  1344.980   1029  1542  190200 10000
#   m2  1542  2570  3083.716   3084  3085  191229 10000
#   m3 26217 30329 35593.596  31871 34442 5843267 10000
#   m4 43180 48321 56988.386  50891 55518 6626173 10000
#   m5 30843 35984 42077.543  37526 40611 6557289 10000
#   m6 40611 44209 50092.131  46779 50891  446714 10000
#   m7 13879 16449 19314.547  17478 19020 6309001 10000
#   m8     0  1028  1256.715   1028  1542   71454 10000

答案 2 :(得分:7)

使用node_modules功能,以及使用回收逻辑索引rep

的可能性
...[c(TRUE, FALSE, TRUE, TRUE)]

如果您使用逻辑向量(rep(3:50, each = 2)[c(TRUE, FALSE, TRUE, TRUE)] ## [1] 3 4 4 5 6 6 7 8 8 9 10 10 11 12 12 13 14 14 15 16 16 17 18 18 19 ## [26] 20 20 21 22 22 23 24 24 25 26 26 27 28 28 29 30 30 31 32 32 33 34 34 35 36 ## [51] 36 37 38 38 39 40 40 41 42 42 43 44 44 45 46 46 47 48 48 49 50 50 / TRUE)作为索引(在FALSE [内),]会导致选择相应的元素和TRUE导致遗漏。如果逻辑索引向量(FALSE)比索引向量(在您的情况下为c(TRUE, FALSE, TRUE, TRUE))短,则索引向量将被重新计算。

另外还有一个注意事项:每当你使用像

这样的R代码时
rep(3:50, each = 2)

 x = c(x, something)

或类似的,你在R中采用类似C的编程风格。这使得你的代码无法复杂,如果使用大型(比如200MB +)数据集,可能会导致低性能和内存不足问题。 R旨在为您提供数据结构的低级修补。

阅读R Inferno,第2圈:成长对象中有关馋嘴及其惩罚的更多信息。

答案 3 :(得分:5)

我能找到的最简单的方法是创建另一个仅包含v <- 3:50 sort(c(v,v[v %% 2 == 0])) # [1] 3 4 4 5 6 6 7 8 8 9 10 10 11 12 12 13 14 14 15 16 16 # 17 18 18 19 20 20 21 22 22 23 24 24 25 26 26 27 28 28 #[40] 29 30 30 31 32 32 33 34 34 35 36 36 37 38 38 39 40 40 41 42 42 # 43 44 44 45 46 46 47 48 48 49 50 50 值的方法(基于OP的意图),然后简单地连接两个向量。例子可能是:

<%= f.label :mobile, "Mobile No:" %>

答案 4 :(得分:4)

这是一个无环路的1行解决方案:

> as.vector(t(cbind(seq(3,49,2),seq(4,50,2),seq(4,50,2))))
 [1]  3  4  4  5  6  6  7  8  8  9 10 10 11 12 12 13 14 14 15 16 16 17
[23] 18 18 19 20 20 21 22 22 23 24 24 25 26 26 27 28 28 29 30 30 31 32
[45] 32 33 34 34 35 36 36 37 38 38 39 40 40 41 42 42 43 44 44 45 46 46
[67] 47 48 48 49 50 50

它形成一个矩阵,其第一列是3:50范围内的奇数,第二列和第三列是该范围内的偶数,然后(通过转置)逐行读取。

嵌套循环方法的问题在于基本模式是长度为3的一个,重复24次(而不是长度为2的模式重复50次)。如果你想使用嵌套循环,外循环可以迭代24次,内循环3.第一次通过外循环可以构造3,4,4。第二遍可以构建5,6,6。等等。由于有24 * 3 = 72个元素,您可以预先分配向量(使用f <- vector("numeric",74)),这样您就不会一次增长1个元素。您在每个阶段使用的习语f <- c(f,i)复制所有旧元素,只是为了创建一个新元素,它只有1个元素。这里的元素太少,无法真正发挥作用,但如果你试图创建大型向量,那么性能可能会非常糟糕。

答案 5 :(得分:4)

Here is a method that combines portions of a couple of the other answers.

rep(seq(3, 50, 2), each=3) + c(0, 1, 1)
 [1]  3  4  4  5  6  6  7  8  8  9 10 10 11 12 12 13 14 14 15 16
[21] 16 17 18 18 19 20 20 21 22 22 23 24 24 25 26 26 27 28 28 29
[41] 30 30 31 32 32 33 34 34 35 36 36 37 38 38 39 40 40 41 42 42
[61] 43 44 44 45 46 46 47 48 48 49 50 50

Here is a second method using cumsum

cumsum(rep(c(1, 1, 0), 24)) + 2L

This should be very quick.

答案 6 :(得分:3)

这也应该这样做。

sort(c(3:50, seq(4, 50, 2)))

答案 7 :(得分:0)

另一个想法,虽然没有与速度最快的解决方案竞争:

mat <- matrix(3:50,nrow=2)
c(rbind(mat,mat[2,]))
# [1]  3  4  4  5  6  6  7  8  8  9 10 10 11 12 12 13 14 14 15 16 16 17 18 18 19 20 20 21 22 22
# [31] 23 24 24 25 26 26 27 28 28 29 30 30 31 32 32 33 34 34 35 36 36 37 38 38 39 40 40 41 42 42
# [61] 43 44 44 45 46 46 47 48 48 49 50 50
相关问题