Extract Consecutive Pairs of Elements from a Vector and Place in a Matrix
This fits your desired output:
cbind(C[-length(C)], C[-1])
[,1] [,2]
[1,] 1 20
[2,] 20 44
[3,] 44 62
[4,] 62 64
[5,] 64 89
[6,] 89 91
[7,] 91 100
How to construct consecutive pairs from a vector with last element included
This should do it
cbind(x, c(x[-1], x[1]))
R iterate over consecutive pairs in a list
We can remove the first
and last
elements and concatenate in Map
Map(c, v1[-length(v1)], v1[-1])
#[[1]]
#[1] 1 2
#[[2]]
#[1] 2 3
#[[3]]
#[1] 3 4
Or rbind
and use asplit
asplit(rbind(v1[-length(v1)], v1[-1]), 2)
R: return largest consecutive pair of numbers in a matrix
Here is a solution using matrix arithmetic that will be much more efficient than a nested loop over the rows and columns, especially on large matrices.
directionalSums <- function(x){
stopifnot(is.matrix(x))
# padding functions to allow matrix addition
padL <- function(x) cbind(-Inf,x)
padR <- function(x) cbind(x,-Inf)
padU <- function(x) rbind(-Inf,x)
padD <- function(x) rbind(x,-Inf)
# these padding functions are just for readability
padLU <- function(x) padL(padU(x))
padLD <- function(x) padL(padD(x))
padRU <- function(x) padR(padU(x))
padRD <- function(x) padR(padD(x))
m <- nrow(x)
n <- ncol(x)
sumR <- padR( (padL(x) + padR(x))[1:m,2:n] )
sumD <- padD( (padU(x) + padD(x))[2:m,1:n])
sumRD <- padRD( (padLU(x) + padRD(x))[2:m,2:n] )
sumRU <- padRU( (padRU(x) + padLD(x))[2:m,2:n] )
list(`right`=sumR,
`down`=sumD,
`right and down`=sumRD,
`right and up`=sumRU)
}
Let's try it out.
(sumList <- directionalSums(ma))
maxLocList <- lapply(sumList, function(x) which(x==max(x), arr.ind=TRUE))
for (i in 1:length(maxLocList) ){
nameD <- names(maxLocList)[i]
startCell <- maxLocList[[i]]
maxSum <- sumList[[i]][startCell]
x1 <- ma[startCell]
x2 <- maxSum - x1
writeLines(paste0('The max-sum consec. pair going ',
nameD, ' starts at [',
paste(startCell, collapse=', '),
'], with sum ', maxSum,
' and components ', x1, ' and ',x2)
)
}
Returns:
$right
[,1] [,2] [,3] [,4]
[1,] 15 13 8 -Inf
[2,] 9 15 24 -Inf
[3,] 12 25 28 -Inf
[4,] 16 26 24 -Inf
$down
[,1] [,2] [,3] [,4]
[1,] 12 12 16 16
[2,] 7 14 26 26
[3,] 4 24 27 25
[4,] -Inf -Inf -Inf -Inf
$`right and down`
[,1] [,2] [,3] [,4]
[1,] 13 17 20 -Inf
[2,] 13 21 22 -Inf
[3,] 18 20 29 -Inf
[4,] -Inf -Inf -Inf -Inf
$`right and up`
[,1] [,2] [,3] [,4]
[1,] -Inf -Inf -Inf -Inf
[2,] 11 11 12 -Inf
[3,] 8 19 30 -Inf
[4,] 10 31 23 -Inf
The max-sum consec. pair going right starts at [3, 3], with sum 28 and components 16 and 12
The max-sum consec. pair going down starts at [3, 3], with sum 27 and components 16 and 11
The max-sum consec. pair going right and down starts at [3, 3], with sum 29 and components 16 and 13
The max-sum consec. pair going right and up starts at [4, 2], with sum 31 and components 15 and 16
Applying a function over consecutive pairs of list elements in R without loops
I use mapply
for that. For example
a<-1:1000
mapply(function(x,y)x-y,a[-1000],a[-1])
It appears to be slightly faster than the for loop version:
> f <- function(x,y)x-y
> g <- function(){
o<-c();
for(i in a[-1000])o<-c(o,f(i,i+1))
> }
>
> system.time(
+ for(i in 1:1000){
+ mapply(f,a[-1000],a[-1])
+ }
+ )
user system elapsed
2.344 0.000 2.345
> system.time(for(i in 1:1000)g())
user system elapsed
3.399 0.000 3.425
Extract and count pairs of adjacent numbers within rows
A base
alternative.
1. Find and count pairs
Because you only have numerical values, we coerce data to matrix. This will make subsequent calculations considerably faster. Create lag and lead versions (column-wise) of the data, i.e. remove the last column (m[ , -ncol(m)]
) and first column (m[ , -ncol(m)]
) respectively.
Coerce the lag and lead data to 'from' and 'to' vectors, and count pairs (table
). Convert table to matrix. Select first pair with max frequency.
m <- as.matrix(d)
tt <- table(from = as.vector(m[ , -ncol(m)]), to = as.vector(m[ , -1]))
m2 <- cbind(from = as.integer(dimnames(tt)[[1]]),
to = rep(as.integer(dimnames(tt)[[2]]), each = dim(tt)[1]),
freq = as.vector(tt))
m3 <- m2[which.max(m2[ , "freq"]), ]
# from to freq
# 3 0 3
If you want all pairs with maximum frequency, use m2[m2[ , "freq"] == max(m2[ , "freq"]), ]
instead.
2. Replace values of most frequent pair and set rest to zero
Make a copy of the original data. Fill it with zero. Grab the 'from' and 'to' values of the 'max pair'. Get indexes of matches in lag and lead data, which correspond to 'from' columns. rbind
with indexes of 'to' columns. At the indexes, replace zeros with 2.
m_bin <- m
m_bin[] <- 0
ix <- which(m[ , -ncol(m)] == m3["from"] &
m[ , -1] == m3["to"],
arr.ind = TRUE)
m_bin[rbind(ix, cbind(ix[ , "row"], ix[ , "col"] + 1))] <- 2
m_bin
# var1 var2 var3 var4 var5
# [1,] 0 0 2 2 0
# [2,] 0 0 2 2 0
# [3,] 2 2 0 0 0
# [4,] 0 0 0 0 0
3. Benchmark
I use data of a size somewhat similar to that mentioned by OP in comment: a data frame with 10000 rows, 100 columns, and sampling from 100 different values.
I compare the code above (f_m()
) with the zoo
answer (f_zoo()
; functions below). To compare the output, I add dimnames
to the zoo
result.
The result shows that f_m
is considerably faster.
set.seed(1)
nr <- 10000
nc <- 100
d <- as.data.frame(matrix(sample(1:100, nr * nc, replace = TRUE),
nrow = nr, ncol = nc))
res_f_m <- f_m(d)
res_f_zoo <- f_zoo(d)
dimnames(res_f_zoo) <- dimnames(res_f_m)
all.equal(res_f_m, res_f_zoo)
# [1] TRUE
system.time(f_m(d))
# user system elapsed
# 0.12 0.01 0.14
system.time(f_zoo(d))
# user system elapsed
# 61.58 26.72 88.45
f_m <- function(d){
m <- as.matrix(d)
tt <- table(from = as.vector(m[ , -ncol(m)]),
to = as.vector(m[ , -1]))
m2 <- cbind(from = as.integer(dimnames(tt)[[1]]),
to = rep(as.integer(dimnames(tt)[[2]]),
each = dim(tt)[1]),
freq = as.vector(tt))
m3 <- m2[which.max(m2[ , "freq"]), ]
m_bin <- m
m_bin[] <- 0
ix <- which(m[ , -ncol(m)] == m3["from"] &
m[ , -1] == m3["to"],
arr.ind = TRUE)
m_bin[rbind(ix, cbind(ix[ , "row"], ix[ , "col"] + 1))] <- 2
return(m_bin)
}
f_zoo <- function(d){
pairs <- sort(table(c(rollapply(t(d), 2, toString))))
top <- scan(text = names(tail(pairs, 1)), sep = ",", what = 0L, quiet = TRUE)
right <- rollapplyr(unname(t(d)), 2, identical, top, fill = FALSE)
left <- rbind(right[-1, ], FALSE)
t(2 * (left | right))
}
How to assign values to a vector in pairs of 10 in R?
After you create your matrix X
and vector X_mean
, you could do:
X[,2] <- rep(c(0,3,5, 10) - X_mean, each = 10)
Extract and store a specific position from multiple matrices in an array in R
If you would like to fix your loop, this could be one way to do it:
unouno <- NULL
for (i in 1:dim(y)[3]){
unouno[i]<-y[2,1,i]
}
It seems that you were mising indexing on the vector unouno as well
Extract difference between every 2 consecutive elements
You can simply use
diff(wss)
which returns a vector of the differences.
To illustrate what you did wrong. lapply should be used on a list and evaluates a function for each element in the list. This is not applicable here because: i) you don't have a list, ii) you need the differences between 2 consecutive elements and in the method you used , even if it were a list, you only supply one to the function diff
numpy create array of the max of consecutive pairs in another array
A loop-free solution is to use max
on the windows created by skimage.util.view_as_windows
:
list(map(max, view_as_windows(A, (2,))))
[8, 33, 33, 4, 6]
Copy/pastable example:
import numpy as np
from skimage.util import view_as_windows
A = np.array([8, 2, 33, 4, 3, 6])
list(map(max, view_as_windows(A, (2,))))
Related Topics
How to Use an R Script from Github
Use of .By and .Eachi in the Data.Table Package
Longtable in a Knitr (Pdf) Document: Using Xtable (Or Kable)
How Does Settimelimit Work in R
Why Should Someone Use {} for Initializing an Empty Object in R
Subtract Values in One Dataframe from Another
Unpacking and Merging Lists in a Column in Data.Frame
How to Make Join Operations in Dplyr Silent
Knitr Inline Chunk Options (No Evaluation) or Just Render Highlighted Code
Nan Is Removed When Using Na.Rm=True
How to Do Str_Extract with Base R
Plot Margins in Rmarkdown/Knitr
Generate 3 Random Number That Sum to 1 in R
Error: X Must Be Atomic for 'Sort.List'
How to Check If Each Element in a Vector Is Integer or Not in R
How to Set Factor Levels to the Order They Appear in a Data Frame
Automatically Detect Date Columns When Reading a File into a Data.Frame