Hi I have a two-column integer matrix like this: R> jj [,1] [,2] [1,] -1 1 [2,] -2 2 [3,] -7 6 [4,] -8 7 [5,] -6 5 [6,] -9 8 [7,] -5 4 [8,] 3 -3 [9,] -10 9 [10,] -4 3 I want a diagnostic that detects whether a row is a multiple of the first row or not. In this case, this would be rows 1,2, and 8. How to do this nicely? Sometimes the first row has a zero, so the method would have to work on [,1] [,2] [1,] 0 1 [2,] 1 1 [3,] 0 8 [4,] 0 -4 [5,] 0 0 [6,] 4 0 > in which case rows 1,3,4,5 are multiples. It'd be nice to have a solution that works for any number of columns. -- Robin Hankin Uncertainty Analyst Southampton Oceanography Centre European Way, Southampton SO14 3ZH, UK tel 023-8059-7743
Robin Hankin <r.hankin <at> soc.soton.ac.uk> writes: : : Hi : : I have a two-column integer matrix like this: : : R> jj : : [,1] [,2] : [1,] -1 1 : [2,] -2 2 : [3,] -7 6 : [4,] -8 7 : [5,] -6 5 : [6,] -9 8 : [7,] -5 4 : [8,] 3 -3 : [9,] -10 9 : [10,] -4 3 : : I want a diagnostic that detects whether a row is a multiple of : the first row or not. In this case, this would be rows 1,2, and 8. : : How to do this nicely? Sometimes the first row has a zero, so the : method would have to work on : : [,1] [,2] : [1,] 0 1 : [2,] 1 1 : [3,] 0 8 : [4,] 0 -4 : [5,] 0 0 : [6,] 4 0 : > : : in which case rows 1,3,4,5 are multiples. It'd be nice to have : a solution that works for any number of columns. If rowi is a multiple of row1 then crossprod(cbind(row1, rowi)) is singular so: apply(mat, 1, function(x) det(crossprod(cbind(x, mat[1,])))) == 0 If your matrix only has two columns then crossprod(x) is singular iff x is so you can eliminate the crossprod.
This works for your first example: f <- function(m) { k <- t(t(m) %/% m[1,]) which(rowSums(k - k[, 1]) == 0) }> f(jj)[1] 1 2 8 but not the second one. The 0s are problematic... Andy> From: Robin Hankin > > Hi > > I have a two-column integer matrix like this: > > > R> jj > > [,1] [,2] > [1,] -1 1 > [2,] -2 2 > [3,] -7 6 > [4,] -8 7 > [5,] -6 5 > [6,] -9 8 > [7,] -5 4 > [8,] 3 -3 > [9,] -10 9 > [10,] -4 3 > > I want a diagnostic that detects whether a row is a multiple of > the first row or not. In this case, this would be rows 1,2, and 8. > > How to do this nicely? Sometimes the first row has a zero, so the > method would have to work on > > [,1] [,2] > [1,] 0 1 > [2,] 1 1 > [3,] 0 8 > [4,] 0 -4 > [5,] 0 0 > [6,] 4 0 > > > > in which case rows 1,3,4,5 are multiples. It'd be nice to have > a solution that works for any number of columns. > > -- > Robin Hankin > Uncertainty Analyst > Southampton Oceanography Centre > European Way, Southampton SO14 3ZH, UK > tel 023-8059-7743 > > ______________________________________________ > R-help at stat.math.ethz.ch mailing list > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide! > http://www.R-project.org/posting-guide.html > >
Robin The attached script works but it ain't pretty/ Martin -- No virus found in this outgoing message. Checked by AVG Anti-Virus.
Sorry! Something went wrong with the attachment in my previous post. Here it is. ------------------------------- intmult <- function(X) { # extract columns with non-zero top cell X1 <- X[,which(X[1,]!=0)] # look for integer multiples in reduced table m <- nrow(X1);n <- ncol(X1) D <- matrix(X1[1,],m,n,byrow=T) X2 <- X1/D ind <- which(rowSums(X2==rowMeans(X2))==n) # build new table of integer multiples X3 <- X[ind,] # remove rows that contain non-zero(s) below top zero ind <- which(X3[1,]==0) lind = length(ind) temp <- X3[,ind]==0 ind2 <- which(rowSums(temp)==lind) X4 <- X3[ind2,] } -- No virus found in this outgoing message. Checked by AVG Anti-Virus.