I've searched the doc for insert and could not find the way to do the following, hope someone can help: Let's say we have a vector:> a[1] "1" "2" "3" "5" "6" "3" and we want to insert a "7" after any given "3", i.e., we want vector a to become: [1] "1" "2" "3" "7" "5" "6" "3" "7" That is, how can we replce one element by more than one elements? (...causing the vector to go beyond its length) Thanks Agus Dr. Agustin Lobo Instituto de Ciencias de la Tierra (CSIC) Lluis Sole Sabaris s/n 08028 Barcelona SPAIN tel 34 93409 5410 fax 34 93411 0012 alobo at ija.csic.es
Agustin, Not sure this is the most effective means, but works:> a[1] 1 2 3 5 6 3> lapply(as.list(a), function(x) if(x==3) x<-c(3,7)else x) -> aa> aa[[1]] [1] 1 [[2]] [1] 2 [[3]] [1] 3 7 [[4]] [1] 5 [[5]] [1] 6 [[6]] [1] 3 7> unlist(aa)[1] 1 2 3 7 5 6 3 7>Basically, convert vector to a list, modify that element of the list matching your condition, then unlist the resulting list. HTH steve Agustin Lobo wrote:> I've searched the doc for insert > and could not find the way to do the following, > hope someone can help: > > Let's say we have a vector: > > a > [1] "1" "2" "3" "5" "6" "3" > > and we want to insert a "7" after > any given "3", i.e., we want vector a > to become: > > [1] "1" "2" "3" "7" "5" "6" "3" "7" > > That is, how can we replce one > element by more than one elements? > (...causing the vector to go beyond its > length) > > Thanks > > Agus > > Dr. Agustin Lobo > Instituto de Ciencias de la Tierra (CSIC) > Lluis Sole Sabaris s/n > 08028 Barcelona SPAIN > tel 34 93409 5410 > fax 34 93411 0012 > alobo at ija.csic.es > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > http://www.stat.math.ethz.ch/mailman/listinfo/r-help
On Mon, Feb 17, 2003 at 02:01:47PM +0100, Agustin Lobo wrote: ...> Let's say we have a vector: > > a > [1] "1" "2" "3" "5" "6" "3" > > and we want to insert a "7" after > any given "3", i.e., we want vector a > to become: > > [1] "1" "2" "3" "7" "5" "6" "3" "7"... No one-step way I can think of. I'd use a "for" loop. a <- c(1,2,3,5,6,3) N <- length(a) for(ii in which(a==3)) { if(ii == N) { a <- c(a,7) } else { a <- c(a[1:ii],7,a[(ii+1):N]) } } Cheers Jason -- Indigo Industrial Controls Ltd. 64-21-343-545 jasont at indigoindustrial.co.nz
Inserting new values into a vector requires to describe where to insert the new values. The function "insert.values" allows you to define the new position(s) by fractional indices or by a logical vector. "insert.values" <- function(x,pos.insert,x.insert){ # insert.values inserts x.insert into x at positions defined by pos.insert # Arguments: # x input vector # x.insert vector of new values to be stored # pos.insert defines the positions of the new values in one of two ways: # a) pos.insert is a vector of fractional numbers of the same length # as x.insert: x.insert[i] will be inserted between # x[ floor(pos.insert) ] and x[ ceiling(pos.insert) ] # b) pos.insert is of mode logical with length(x) values FALSE # and length(x.insert) values TRUE. Then TRUE values indicate # the position of the new elements and FALSE the values # of old ones # # Examples: # > x<-1:5 # > insert.values(x, 2.5, 1000) # [1] 1 2 1000 3 4 5 # > insert.values(x, (1:5)+.2, 1001:1005) # [1] 1 1001 2 1002 3 1003 4 1004 5 1005 # > insert.values(x, .9, 1111) # [1] 1111 1 2 3 4 5 # > insert.values(x, c(T,rep(F,5)), 1000) # [1] 1000 1 2 3 4 5 # > insert.values(x, c(rep(F,5),T), 1000) # [1] 1 2 3 4 5 1000 # > insert.values(x, rbind(rep(F,5),T), 1001:1005) # [1] 1 1001 2 1002 3 1003 4 1004 5 1005 # pw 02/2003 if(is.logical(pos.insert)){ pos.insert <- pos.insert[pos.insert]/length(pos.insert) + cumsum(!pos.insert)[pos.insert] } x<-c(x,x.insert)[order(c(seq(x),pos.insert))] return(x) } Peter Wolf -------------------------------------- Dr. Agustin Lobo wrote:> I''ve searched the doc for insert > and could not find the way to do the following, > hope someone can help: > > Let''s say we have a vector: > > a > [1] "1" "2" "3" "5" "6" "3" > > and we want to insert a "7" after > any given "3", i.e., we want vector a > to become: > > [1] "1" "2" "3" "7" "5" "6" "3" "7"------------------------------------------------------------------------------- Peter Wolf, Statistik/Informatik, Fak.f.Wiwi, Uni Bielefeld pwolf@wiwi.uni-bielefeld.de, http://www.wiwi.uni-bielefeld.de/~wolf/wolf.html ------------------------------------------------------------------------------- [[alternate HTML version deleted]]
> From: Peter Wolf <pwolf at wiwi.uni-bielefeld.de> > > "insert.values" <- function(x,pos.insert,x.insert){ > :Which when reduced to its bare minimum to solve the stated problem, becomes: threes <- which(a==3) a <- c(a, rep(7, length(threes)))[order(c(seq(a), threes))] This is by far the overall fastest solution so far proposed, and certainly is reasonably easy to understand. However an even faster solution is based on rep(): N <- which(threes <- a == 3) # which ones a <- rep(a, times = 1 + threes) # duplicate them a[N + 1:length(N)] <- 7 # replace the duplicates Relative timing for vector lengths n=1000 and n=10000 with 1000 repeats (on a 1.7GHz P4 running R-1.6.1 under NetBSD) is as follows: a <- sample(1:9, n, TRUE) n=1000 n=10000 lapply (Stephen Upton and Peter Dalgaard) 9.2s 117.8s recursion (John Fox) [options(expressions=n)] 59.9s stack overflow offset <- (Thomas Lumley) 1.4s 12.7s offset <- (Peter Dalgaard) 1.3s 10.9s order() (Peter Wolf) 1.1s 8.7s rep() (me) 0.9s 7.6s Hope this helps, Ray Brownrigg <ray at mcs.vuw.ac.nz> http://www.mcs.vuw.ac.nz/~ray