Transforming from Mixed-sign to Nonnegative Data

Description

nneg is a generic function to transform a data objects that contains negative values into a similar object that only contains values that are nonnegative or greater than a given threshold.

posneg is a shortcut for nneg(..., method='posneg'), to split mixed-sign data into its positive and negative part. See description for method "posneg", in nneg.

rposneg performs the "reverse" transformation of the posneg function.

Usage

nneg(object, ...)

S4 (matrix)
`nneg`(object, method = c("pmax", "posneg", "absolute", "min"), threshold = 0, 
  shift = TRUE)

posneg(...)

rposneg(object, ...)

S4 (matrix)
`rposneg`(object, unstack = TRUE)

Arguments

object
The data object to transform
...
extra arguments to allow extension or passed down to nneg,matrix or rposneg,matrix in subsequent calls.
method
Name of the transformation method to use, that is partially matched against the following possible methods:
  1. pmaxEach entry is constrained to be above threshold threshold.
  2. posnegThe matrix is split into its "positive" and "negative" parts, with the entries of each part constrained to be above threshold threshold. The result consists in these two parts stacked in rows (i.e. rbind-ed) into a single matrix, which has double the number of rows of the input matrix object.
  3. absoluteThe absolute value of each entry is constrained to be above threshold threshold.
  4. minGlobal shift by adding the minimum entry to each entry, only if it is negative, and then apply threshold.
threshold
Nonnegative lower threshold value (single numeric). See argument shit for details on how the threshold is used and affects the result.
shift
a logical indicating whether the entries below the threshold value threshold should be forced (shifted) to 0 (default) or to the threshold value itself. In other words, if shift=TRUE (default) all entries in the result matrix are either 0 or strictly greater than threshold. They are all greater or equal than threshold otherwise.
unstack
Logical indicating whether the positive and negative parts should be unstacked and combined into a matrix as pos - neg, which contains half the number of rows of object (default), or left stacked as [pos; -neg].

Value

an object of the same class as argument object.

an object of the same type of object

Methods

  1. nnegsignature(object = "matrix"): Transforms a mixed-sign matrix into a nonnegative matrix, optionally apply a lower threshold. This is the workhorse method, that is eventually called by all other methods defined in the NMF package.

  2. nnegsignature(object = "NMF"): Apply nneg to the basis matrix of an NMF object (i.e. basis(object)). All extra arguments in ... are passed to the method nneg,matrix.

  3. rposnegsignature(object = "NMF"): Apply rposneg to the basis matrix of an NMF object.

Examples


# random mixed sign data (normal distribution)
set.seed(1)
x <- rmatrix(5,5, rnorm, mean=0, sd=5)
x
##         [,1]   [,2]    [,3]     [,4]    [,5]
## [1,] -3.1323 -4.102   7.559 -0.22467  4.5949
## [2,]  0.9182  2.437   1.949 -0.08095  3.9107
## [3,] -4.1781  3.692  -3.106  4.71918  0.3728
## [4,]  7.9764  2.879 -11.073  4.10611 -9.9468
## [5,]  1.6475 -1.527   5.625  2.96951  3.0991

# pmax (default)
nneg(x)
##        [,1]  [,2]  [,3]  [,4]   [,5]
## [1,] 0.0000 0.000 7.559 0.000 4.5949
## [2,] 0.9182 2.437 1.949 0.000 3.9107
## [3,] 0.0000 3.692 0.000 4.719 0.3728
## [4,] 7.9764 2.879 0.000 4.106 0.0000
## [5,] 1.6475 0.000 5.625 2.970 3.0991
# using a threshold
nneg(x, threshold=2)
##       [,1]  [,2]  [,3]  [,4]  [,5]
## [1,] 0.000 0.000 7.559 0.000 4.595
## [2,] 0.000 2.437 0.000 0.000 3.911
## [3,] 0.000 3.692 0.000 4.719 0.000
## [4,] 7.976 2.879 0.000 4.106 0.000
## [5,] 0.000 0.000 5.625 2.970 3.099
# without shifting the entries lower than threshold
nneg(x, threshold=2, shift=FALSE)
##       [,1]  [,2]  [,3]  [,4]  [,5]
## [1,] 2.000 2.000 7.559 2.000 4.595
## [2,] 2.000 2.437 2.000 2.000 3.911
## [3,] 2.000 3.692 2.000 4.719 2.000
## [4,] 7.976 2.879 2.000 4.106 2.000
## [5,] 2.000 2.000 5.625 2.970 3.099

# posneg: split positive and negative part
nneg(x, method='posneg')
##         [,1]  [,2]   [,3]    [,4]   [,5]
##  [1,] 0.0000 0.000  7.559 0.00000 4.5949
##  [2,] 0.9182 2.437  1.949 0.00000 3.9107
##  [3,] 0.0000 3.692  0.000 4.71918 0.3728
##  [4,] 7.9764 2.879  0.000 4.10611 0.0000
##  [5,] 1.6475 0.000  5.625 2.96951 3.0991
##  [6,] 3.1323 4.102  0.000 0.22467 0.0000
##  [7,] 0.0000 0.000  0.000 0.08095 0.0000
##  [8,] 4.1781 0.000  3.106 0.00000 0.0000
##  [9,] 0.0000 0.000 11.073 0.00000 9.9468
## [10,] 0.0000 1.527  0.000 0.00000 0.0000
nneg(x, method='pos', threshold=2)
##        [,1]  [,2]   [,3]  [,4]  [,5]
##  [1,] 0.000 0.000  7.559 0.000 4.595
##  [2,] 0.000 2.437  0.000 0.000 3.911
##  [3,] 0.000 3.692  0.000 4.719 0.000
##  [4,] 7.976 2.879  0.000 4.106 0.000
##  [5,] 0.000 0.000  5.625 2.970 3.099
##  [6,] 3.132 4.102  0.000 0.000 0.000
##  [7,] 0.000 0.000  0.000 0.000 0.000
##  [8,] 4.178 0.000  3.106 0.000 0.000
##  [9,] 0.000 0.000 11.073 0.000 9.947
## [10,] 0.000 0.000  0.000 0.000 0.000

# absolute
nneg(x, method='absolute')
##        [,1]  [,2]   [,3]    [,4]   [,5]
## [1,] 3.1323 4.102  7.559 0.22467 4.5949
## [2,] 0.9182 2.437  1.949 0.08095 3.9107
## [3,] 4.1781 3.692  3.106 4.71918 0.3728
## [4,] 7.9764 2.879 11.073 4.10611 9.9468
## [5,] 1.6475 1.527  5.625 2.96951 3.0991
nneg(x, method='abs', threshold=2)
##       [,1]  [,2]   [,3]  [,4]  [,5]
## [1,] 3.132 4.102  7.559 0.000 4.595
## [2,] 0.000 2.437  0.000 0.000 3.911
## [3,] 4.178 3.692  3.106 4.719 0.000
## [4,] 7.976 2.879 11.073 4.106 9.947
## [5,] 0.000 0.000  5.625 2.970 3.099

# min
nneg(x, method='min')
##        [,1]   [,2]   [,3]  [,4]   [,5]
## [1,]  7.941  6.971 18.632 10.85 15.668
## [2,] 11.992 13.511 13.023 10.99 14.984
## [3,]  6.895 14.765  7.967 15.79 11.446
## [4,] 19.050 13.952  0.000 15.18  1.127
## [5,] 12.721  9.547 16.698 14.04 14.173
nneg(x, method='min', threshold=2)
##        [,1]   [,2]   [,3]  [,4]  [,5]
## [1,]  7.941  6.971 18.632 10.85 15.67
## [2,] 11.992 13.511 13.023 10.99 14.98
## [3,]  6.895 14.765  7.967 15.79 11.45
## [4,] 19.050 13.952  0.000 15.18  0.00
## [5,] 12.721  9.547 16.698 14.04 14.17
# random
M <- nmfModel(x, rmatrix(ncol(x), 3))
## Warning: Dimensions of W and H look strange [ncol(W)= 5 > ncol(H)= 3 ]
nnM <- nneg(M)
## Warning: Dimensions of W and H look strange [ncol(W)= 5 > ncol(H)= 3 ]
basis(nnM)
##        [,1]  [,2]  [,3]  [,4]   [,5]
## [1,] 0.0000 0.000 7.559 0.000 4.5949
## [2,] 0.9182 2.437 1.949 0.000 3.9107
## [3,] 0.0000 3.692 0.000 4.719 0.3728
## [4,] 7.9764 2.879 0.000 4.106 0.0000
## [5,] 1.6475 0.000 5.625 2.970 3.0991
# mixture coefficients are not affected
identical( coef(M), coef(nnM) )
## [1] TRUE
# shortcut for the "posneg" transformation
posneg(x)
##         [,1]  [,2]   [,3]    [,4]   [,5]
##  [1,] 0.0000 0.000  7.559 0.00000 4.5949
##  [2,] 0.9182 2.437  1.949 0.00000 3.9107
##  [3,] 0.0000 3.692  0.000 4.71918 0.3728
##  [4,] 7.9764 2.879  0.000 4.10611 0.0000
##  [5,] 1.6475 0.000  5.625 2.96951 3.0991
##  [6,] 3.1323 4.102  0.000 0.22467 0.0000
##  [7,] 0.0000 0.000  0.000 0.08095 0.0000
##  [8,] 4.1781 0.000  3.106 0.00000 0.0000
##  [9,] 0.0000 0.000 11.073 0.00000 9.9468
## [10,] 0.0000 1.527  0.000 0.00000 0.0000
posneg(x, 2)
##        [,1]  [,2]   [,3]  [,4]  [,5]
##  [1,] 0.000 0.000  7.559 0.000 4.595
##  [2,] 0.000 2.437  0.000 0.000 3.911
##  [3,] 0.000 3.692  0.000 4.719 0.000
##  [4,] 7.976 2.879  0.000 4.106 0.000
##  [5,] 0.000 0.000  5.625 2.970 3.099
##  [6,] 3.132 4.102  0.000 0.000 0.000
##  [7,] 0.000 0.000  0.000 0.000 0.000
##  [8,] 4.178 0.000  3.106 0.000 0.000
##  [9,] 0.000 0.000 11.073 0.000 9.947
## [10,] 0.000 0.000  0.000 0.000 0.000
# random mixed sign data (normal distribution)
set.seed(1)
x <- rmatrix(5,5, rnorm, mean=0, sd=5)
x
##         [,1]   [,2]    [,3]     [,4]    [,5]
## [1,] -3.1323 -4.102   7.559 -0.22467  4.5949
## [2,]  0.9182  2.437   1.949 -0.08095  3.9107
## [3,] -4.1781  3.692  -3.106  4.71918  0.3728
## [4,]  7.9764  2.879 -11.073  4.10611 -9.9468
## [5,]  1.6475 -1.527   5.625  2.96951  3.0991

# posneg-transform: split positive and negative part
y <- posneg(x)
dim(y)
## [1] 10  5
# posneg-reverse
z <- rposneg(y)
identical(x, z)
## [1] TRUE
rposneg(y, unstack=FALSE)
##          [,1]   [,2]    [,3]     [,4]    [,5]
##  [1,]  0.0000  0.000   7.559  0.00000  4.5949
##  [2,]  0.9182  2.437   1.949  0.00000  3.9107
##  [3,]  0.0000  3.692   0.000  4.71918  0.3728
##  [4,]  7.9764  2.879   0.000  4.10611  0.0000
##  [5,]  1.6475  0.000   5.625  2.96951  3.0991
##  [6,] -3.1323 -4.102   0.000 -0.22467  0.0000
##  [7,]  0.0000  0.000   0.000 -0.08095  0.0000
##  [8,] -4.1781  0.000  -3.106  0.00000  0.0000
##  [9,]  0.0000  0.000 -11.073  0.00000 -9.9468
## [10,]  0.0000 -1.527   0.000  0.00000  0.0000

# But posneg-transformation with a non zero threshold is not reversible
y1 <- posneg(x, 1)
identical(rposneg(y1), x)
## [1] FALSE
# random mixed signed NMF model
M <- nmfModel(rmatrix(10, 3, rnorm), rmatrix(3, 4))
# split positive and negative part
nnM <- posneg(M)
M2 <- rposneg(nnM)
identical(M, M2)
## [1] TRUE

See also

pmax Other transforms: t.NMF