basically I need to create a sliding window in a string. a way to explain this is:> v <- c("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y") > window <- 5 > shift <- 2I want a matrix of characters with "window" columns filled with "v" by filling a row, then shifting over "shift" and continuing to the next row until "v" is exhausted. You can assume "v" will evenly fit "m" so the result needs to look like this matrix where each row is shifted 2 (in this case):> m[,1] [,2] [,3] [,4] [,5] [1,] "a" "b" "c" "d" "e" [2,] "c" "d" "e" "f" "g" [3,] "e" "f" "g" "h" "i" [4,] "g" "h" "i" "j" "k" [5,] "i" "j" "k" "l" "m" [6,] "k" "l" "m" "n" "o" [7,] "m" "n" "o" "p" "q" [8,] "o" "p" "q" "r" "s" [9,] "q" "r" "s" "t" "u" [10,] "s" "t" "u" "v" "w" [11,] "t" "u" "v" "w" "x" This needs to be very efficient as my data is large, loops would be too slow. Any ideas? It could also be done in a string and then put into the matrix but I don't think this would be easier. I will want to put this in a function: shiftedMatrix <- function(v, window=5, shift=2){... return(m)} thanks dhs [[alternative HTML version deleted]]
Tena koe David Something like: matrix(v[1:win + rep(seq(0, (length(v)-5), shift), each=win)], ncol=win, byrow=TRUE) should work (I haven't tested it fully). Note it gives a different answer to your m since I think the last line of your m is incorrect. HTH .... Peter Alspach> -----Original Message----- > From: r-help-bounces at r-project.org [mailto:r-help-bounces at r- > project.org] On Behalf Of david hilton shanabrook > Sent: Tuesday, 15 June 2010 3:47 p.m. > To: r-help at r-project.org > Subject: [R] shifted window of string > > basically I need to create a sliding window in a string. a way to > explain this is: > > > v <- >c("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","> r","s","t","u","v","w","x","y") > > window <- 5 > > shift <- 2 > > I want a matrix of characters with "window" columns filled with "v" by > filling a row, then shifting over "shift" and continuing to the next > row until "v" is exhausted. You can assume "v" will evenly fit "m" > > so the result needs to look like this matrix where each row is shifted > 2 (in this case): > > > m > [,1] [,2] [,3] [,4] [,5] > [1,] "a" "b" "c" "d" "e" > [2,] "c" "d" "e" "f" "g" > [3,] "e" "f" "g" "h" "i" > [4,] "g" "h" "i" "j" "k" > [5,] "i" "j" "k" "l" "m" > [6,] "k" "l" "m" "n" "o" > [7,] "m" "n" "o" "p" "q" > [8,] "o" "p" "q" "r" "s" > [9,] "q" "r" "s" "t" "u" > [10,] "s" "t" "u" "v" "w" > [11,] "t" "u" "v" "w" "x" > > This needs to be very efficient as my data is large, loops would betoo> slow. Any ideas? It could also be done in a string and then put into > the matrix but I don't think this would be easier. > > I will want to put this in a function: > > shiftedMatrix <- function(v, window=5, shift=2){... > > return(m)} > > thanks > > dhs > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting- > guide.html > and provide commented, minimal, self-contained, reproducible code.
On Jun 14, 2010, at 11:46 PM, david hilton shanabrook wrote:> basically I need to create a sliding window in a string. a way to > explain this is: > >> v <- >> c >> ("a >> ","b >> ","c >> ","d >> ","e >> ","f >> ","g >> ","h >> ","i >> ","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y") >> window <- 5 >> shift <- 2 > > I want a matrix of characters with "window" columns filled with "v" > by filling a row, then shifting over "shift" and continuing to the > next row until "v" is exhausted. You can assume "v" will evenly fit > "m" > > so the result needs to look like this matrix where each row is > shifted 2 (in this case): > >> m > [,1] [,2] [,3] [,4] [,5] > [1,] "a" "b" "c" "d" "e" > [2,] "c" "d" "e" "f" "g" > [3,] "e" "f" "g" "h" "i" > [4,] "g" "h" "i" "j" "k" > [5,] "i" "j" "k" "l" "m" > [6,] "k" "l" "m" "n" "o" > [7,] "m" "n" "o" "p" "q" > [8,] "o" "p" "q" "r" "s" > [9,] "q" "r" "s" "t" "u" > [10,] "s" "t" "u" "v" "w" > [11,] "t" "u" "v" "w" "x"I think you got the last row wrong: > m <- matrix(v[sapply(1:window, function(x) seq(x, (length(v)-window+x) , by = shift))], ncol=window) > m [,1] [,2] [,3] [,4] [,5] [1,] "a" "b" "c" "d" "e" [2,] "c" "d" "e" "f" "g" [3,] "e" "f" "g" "h" "i" [4,] "g" "h" "i" "j" "k" [5,] "i" "j" "k" "l" "m" [6,] "k" "l" "m" "n" "o" [7,] "m" "n" "o" "p" "q" [8,] "o" "p" "q" "r" "s" [9,] "q" "r" "s" "t" "u" [10,] "s" "t" "u" "v" "w" [11,] "u" "v" "w" "x" "y"> > This needs to be very efficient as my data is large, loops would be > too slow. Any ideas? It could also be done in a string and then > put into the matrix but I don't think this would be easier.I'm not sure what you mean, but I think I might have done it the way you thought was harder. There might be a more efficient route with modulo arithmetic. Some elaboration of > v[((1:11)*4)%/%2 -1] [1] "a" "c" "e" "g" "i" "k" "m" "o" "q" "s" "u" But I don't see it immediately.> > I will want to put this in a function: > > shiftedMatrix <- function(v, window=5, shift=2){... > > return(m)}Left as an exercise for the reader. -- David.
Try this: v <- letters; windows <- 5; shift <- 2 e <- embed(v, window) e[seq(1, nrow(e), shift), window:1] On Mon, Jun 14, 2010 at 11:46 PM, david hilton shanabrook <davidshanabrook at me.com> wrote:> basically I need to create a sliding window in a string. ?a way to explain this is: > >> v <- c("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y") >> window <- 5 >> shift <- 2 > > I want a matrix of characters with "window" columns filled with "v" by filling a row, then shifting over "shift" and continuing to the next row until "v" is exhausted. ?You can assume "v" will evenly fit "m" > > so the result needs to look like this matrix where each row is shifted 2 (in this case): > >> m > ? ? ?[,1] [,2] [,3] [,4] [,5] > ?[1,] "a" ?"b" ?"c" ?"d" ?"e" > ?[2,] "c" ?"d" ?"e" ?"f" ?"g" > ?[3,] "e" ?"f" ?"g" ?"h" ?"i" > ?[4,] "g" ?"h" ?"i" ?"j" ?"k" > ?[5,] "i" ?"j" ?"k" ?"l" ?"m" > ?[6,] "k" ?"l" ?"m" ?"n" ?"o" > ?[7,] "m" ?"n" ?"o" ?"p" ?"q" > ?[8,] "o" ?"p" ?"q" ?"r" ?"s" > ?[9,] "q" ?"r" ?"s" ?"t" ?"u" > [10,] "s" ?"t" ?"u" ?"v" ?"w" > [11,] "t" ?"u" ?"v" ?"w" ?"x" > > This needs to be very efficient as my data is large, loops would be too slow. ?Any ideas? ?It could also be done in a string and then put into the matrix but I don't think this would be easier. > > I will want to put this in a function: > > shiftedMatrix <- function(v, window=5, shift=2){... > > return(m)} > > thanks > > dhs > ? ? ? ?[[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >
On Mon, 14 Jun 2010, david hilton shanabrook wrote:> basically I need to create a sliding window in a string. a way to explain this is: > >> v <- c("a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y") >> window <- 5 >> shift <- 2 > > I want a matrix of characters with "window" columns filled with "v" by filling a row, then shifting over "shift" and continuing to the next row until "v" is exhausted. You can assume "v" will evenly fit "m" > > so the result needs to look like this matrix where each row is shifted 2 (in this case): > >> m > [,1] [,2] [,3] [,4] [,5] > [1,] "a" "b" "c" "d" "e" > [2,] "c" "d" "e" "f" "g" > [3,] "e" "f" "g" "h" "i" > [4,] "g" "h" "i" "j" "k" > [5,] "i" "j" "k" "l" "m" > [6,] "k" "l" "m" "n" "o" > [7,] "m" "n" "o" "p" "q" > [8,] "o" "p" "q" "r" "s" > [9,] "q" "r" "s" "t" "u" > [10,] "s" "t" "u" "v" "w" > [11,] "t" "u" "v" "w" "x"The last row is wrong. It is only shifted by 1. Try [11,] "u" "v" "w" "x" "y"> > This needs to be very efficient as my data is large, loops would be too slow.And you know this because you tried it out and timed it?? Please see ?system.time If window is not too big, for( j in 1:window ) m[ , j ] <- v[ j + v.seq ] for a suitable v.seq will be pretty quick. For a vectorized solution, some combination of these pieces seq( window, length(v), by=shift ) (1-window):0 outer( ... , '+') or rep(...) + rep( ... ) v[ ... ] matrix( ... ) will give you the answer. If the problem is so big that neither of these approaches suffices, this is a good candidate for the inline package - one line of C code is all that is needed. HTH, Chuck Any ideas? It could also be done in a string and then put into the matrix but I don't think this would be easier.> > I will want to put this in a function: > > shiftedMatrix <- function(v, window=5, shift=2){... > > return(m)} > > thanks > > dhs > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >Charles C. Berry (858) 534-2098 Dept of Family/Preventive Medicine E mailto:cberry at tajo.ucsd.edu UC San Diego http://famprevmed.ucsd.edu/faculty/cberry/ La Jolla, San Diego 92093-0901