I'm trying to name a vector with only a single column, i.e. say I have
vector<-c(1,2,3,4)
I want to name a single column of (1,2,3,4) as "a", i.e. I want something like:
a
1
2
3
4
If I try
colnames(vector)<- c("a")
It gives me output:
Error in `colnames<-`(`*tmp*`, value = "a") :
attempt to set 'colnames' on an object with less than two dimensions
If I try
names(vector)<- c("a")
Vector is named as
a <NA> <NA> <NA>
1 2 3 4
My question is if such a vector is allowed in R? Specifically, is this allowed without using a matrix or data.frame or any other such class which can store more than one columns? If yes, how do I create it?
If you want something with a column name and that will print in the column format then use a single column matrix or data.frame:
vector <- matrix( c(1,2,3,4), dimnames=list(NULL, "a") )
vector <- data.frame( a=c(1,2,3,4) )
There is a 1d object type but rather confusingly it requires that the assignment of a single dimension value to be its length. See:
?dim
dim(vector)=1L
Error in dim(vector) = 1L :
dims [product 1] do not match the length of object [4]
> dim(vector)=4L
> vector
[1] 1 2 3 4
> str(vector)
num [1:4(1d)] 1 2 3 4
Actually the dim function help page doesn't appear to document the requirement that the product of the dim-result will equal the length. My guess is that your homework assignment was intended to get you to read the dim help page and then discover (as I just did) that a one-d object is possible but a bit confusing.
As it turns out the distinction between row and column vectors is not enforced:
> vector %*% matrix(1:16,4)
[,1] [,2] [,3] [,4]
[1,] 30 70 110 150
> t(vector) %*% matrix(1:16,4)
[,1] [,2] [,3] [,4]
[1,] 30 70 110 150
> t(vector) %*% matrix(1:16,4) %*% vector
[,1]
[1,] 1100
> vector %*% matrix(1:16,4) %*% vector
[,1]
[1,] 1100
Related
So I have a large list of matrices and I want to be able to take them one by one and unlist them into their normal 2D individual matrices. So let's say I have a list of matrices examplelist. I obtained the list with this code:
examplelist <- lapply(listofimages, readImage)
And here is one sample image 512x512 .tif which would be one of the matrices in the list of matrices :
The list looks like this:
I want to take out one matrix at a time as a 2D 512x512 matrix but when I try to trim out the other data manually its still a list element (single quotes to make the index not referenced):
a <- as.matrix(examplelist['1'])
b <- a[,]
And when I do this it flattens into a 1D vector:
b <- as.numeric(unlist(examplelist['1']))
Which is 262144 x 1 instead of 512 x 512.
Ive tried converting it to a data table, data frame, and a few other things and then when I get to trying to make it numeric:
as.numeric(b)
I get this error:
Using dput, it lists this as the error:
Is there an easy way to unlist a square matrix from a list of matrices and get it in its original 512 x 512 form rather than a 1D vector (as seen above)?
I tried trimming dimensions (seen above) to get rid of some of the other info but it threw an error. I also tried accessing just the data attributes using '#' and '$' but that didn't work either.
If I try this:
b <- as.data.table(examplelist['1'])
It just gives me another 262144 x 1 1D vector instead of the desired 2D matrix.
This solution and this, don't work because I dont want a 1D vector or to only convert elements (I want the whole matrix) as numeric elements.
To extract an element of a list you need to use double brackets. Consider the example below. Let's create a list of matrices.
# Dummy list
foo <- list(first = matrix(runif(16), ncol = 4),
second = matrix(runif(16), ncol = 4))
This looks like the following:
# Quick peek
print(foo)
#> $first
#> [,1] [,2] [,3] [,4]
#> [1,] 0.3517863 0.1222894 0.69358440 0.7850944
#> [2,] 0.7516454 0.9881041 0.72152473 0.3035514
#> [3,] 0.8540138 0.3966431 0.40551019 0.3687717
#> [4,] 0.8872717 0.7438446 0.03258007 0.1305907
#>
#> $second
#> [,1] [,2] [,3] [,4]
#> [1,] 0.57426947 0.59617809 0.05355548 0.05962695
#> [2,] 0.60420788 0.06640785 0.43616808 0.03359352
#> [3,] 0.44216820 0.58033207 0.22686284 0.42624557
#> [4,] 0.08838313 0.27258925 0.71353586 0.76606084
Now, let's have a look at the first element using just one set of brackets.
# Extract one element as a list
a <- foo['first'] # Or foo[1]
# Examine output
print(a)
#> $first
#> [,1] [,2] [,3] [,4]
#> [1,] 0.3517863 0.1222894 0.69358440 0.7850944
#> [2,] 0.7516454 0.9881041 0.72152473 0.3035514
#> [3,] 0.8540138 0.3966431 0.40551019 0.3687717
#> [4,] 0.8872717 0.7438446 0.03258007 0.1305907
class(a)
#> [1] "list"
You'll notice it's a list. Let's try using two sets of brackets.
# Extract one element
b <- foo[['first']] # Or foo[[1]]
# Examine output
print(b)
#> [,1] [,2] [,3] [,4]
#> [1,] 0.3517863 0.1222894 0.69358440 0.7850944
#> [2,] 0.7516454 0.9881041 0.72152473 0.3035514
#> [3,] 0.8540138 0.3966431 0.40551019 0.3687717
#> [4,] 0.8872717 0.7438446 0.03258007 0.1305907
class(b)
#> [1] "matrix"
Created on 2019-06-18 by the reprex package (v0.3.0)
It's a matrix! Plus, it maintains the original structure of the matrix.
I have the following matrices :
> matrix <- matrix(c(1,3,4,NA,NA,NA,3,0,4,6,0,NA,2,NA,NA,2,0,1,0,0), nrow=5,ncol=4)
> n <- matrix(c(1,2,5,6,2),nrow=5,ncol=1)
As you can see, for each rows I have
multiple NAs - the number NAs is undefined
ONE single "0"
I would like to subset the 0 for the values of the n. Intended output below.
> output <- matrix(c(1, 3, 4,NA,NA,NA,3,5,4,6,1,NA,2,NA,NA,2,2,1,6,2), nrow=5,ncol=4)
I have tried the following
subset <- matrix == 0 & !is.na(matrix)
matrix[subset] <- n
#does not give intended output, but subset locates the values i want to change
When used on my "real" data i get the following message :
Warning message: In m[subset] <- n : number of items to replace is not
a multiple of replacement length
Thanks
EDIT : added a row to the matrix, as my real life problem is with an unbalanced matrix. I am using Matrices and not DF here, because i think (not sure)that with very large datasets, R is quicker with large matrices rather than subsets of dataframes.
We can do this using
out1 <- matrix+n[row(matrix)]*(matrix==0)
identical(output, out1)
#[1] TRUE
It appears you want to replace the values by row, but subsetting is replacing the values by column (and maybe that's not a completely thorough explanation). Transposing the matrix will get the desired output:
matrix <- t(matrix)
subset <- matrix == 0 & !is.na(matrix)
matrix[subset] <- n
matrix <- t(matrix)
setequal(output, matrix)
[1] TRUE
You can try this option with ifelse:
ifelse(matrix == 0, c(n) * (matrix == 0), matrix)
# [,1] [,2] [,3] [,4]
#[1,] 1 NA 1 2
#[2,] 3 NA NA 2
#[3,] 4 3 5 NA
#[4,] NA 6 NA 2
zero = matrix == 0
identical(ifelse(zero, c(n) * zero, matrix), output)
# [1] TRUE
I am trying to find out usage of drop() function. I read the documentation that a matrix or array can be the input object for the function however the size of the matrix or object does not change. Can someone explain its actual usage and how it works?
I am using R version 3.2.1. Code snippet:
data1 <- matrix(data=(1:10),nrow=1,ncol=1)
drop(data1)
R has factors, which are very cool (and somewhat analogous to labeled levels in Stata). Unfortunately, the factor list sticks around even if you remove some data such that no examples of a particular level still exist.
# Create some fake data
x <- as.factor(sample(head(colors()),100,replace=TRUE))
levels(x)
x <- x[x!="aliceblue"]
levels(x) # still the same levels
table(x) # even though one level has 0 entries!
The solution is simple: run factor() again:
x <- factor(x)
levels(x)
If you need to do this on many factors at once (as is the case with a data.frame containing several columns of factors), use drop.levels() from the gdata package:
x <- x[x!="antiquewhite1"]
df <- data.frame(a=x,b=x,c=x)
df <- drop.levels(df)
R matrix is a two dimensional array. R has a lot of operator and functions that make matrix handling very convenient.
Matrix assignment:
>A <- matrix(c(3,5,7,1,9,4),nrow=3,ncol=2,byrow=TRUE)
>A
[,1] [,2]
[1,] 3 5
[2,] 7 1
[3,] 9 4
Matrix row and column count:
>rA <- nrow(A)
>rA
[1] 3
>cA <- ncol(A)
>cA
[1] 2
t(A) function returns a transposed matrix of A:
>B <- t(A)
>B
[,1] [,2] [,3]
[1,] 3 7 9
[2,] 5 1 4
Matrix multplication:
C <- A * A
C
[,1] [,2]
[1,] 9 25
[2,] 49 1
[3,] 81 16
Matrix Addition:
>C <- A + A
>C
[,1] [,2]
[1,] 6 10
[2,] 14 2
[3,] 18 8
Matrix subtraction (-) and division (/) operations ... ...
Sometimes a matrix needs to be sorted by a specific column, which can be done by using order() function.
Following is a csv file example:
,t1,t2,t3,t4,t5,t6,t7,t8
r1,1,0,1,0,0,1,0,2
r2,1,2,5,1,2,1,2,1
r3,0,0,9,2,1,1,0,1
r4,0,0,2,1,2,0,0,0
r5,0,2,15,1,1,0,0,0
r6,2,2,3,1,1,1,0,0
r7,2,2,3,1,1,1,0,1
Following R code will read in the above file into a matrix, and sort it by column 4, then write to a output file:
x <- read.csv("sortmatrix.csv",header=T,sep=",");
x <- x[order(x[,4]),];
x <- write.table(x,file="tp.txt",sep=",")
The result is:
"X","t1","t2","t3","t4","t5","t6","t7","t8"
"1","r1",1,0,1,0,0,1,0,2
"4","r4",0,0,2,1,2,0,0,0
"6","r6",2,2,3,1,1,1,0,0
"7","r7",2,2,3,1,1,1,0,1
"2","r2",1,2,5,1,2,1,2,1
"3","r3",0,0,9,2,1,1,0,1
"5","r5",0,2,15,1,1,0,0,0
The DROP function supports natively compiled, scalar user-defined functions.
Removes one or more user-defined functions from the current database
To execute DROP FUNCTION, at a minimum, a user must have ALTER permission on the schema to which the function belongs, or CONTROL permission on the function.
DROP FUNCTION will fail if there are Transact-SQL functions or views in the database that reference this function and were created by using SCHEMA BINDING, or if there are computed columns, CHECK constraints, or DEFAULT constraints that reference the function.
DROP FUNCTION will fail if there are computed columns that reference this function and have been indexed.
DROP FUNCTION { [ schema_name. ] function_name } [ ,...n ]
I'm trying to subset a matrix so that I only get the matrix where the first variable is larger than the second variable. I have the matrix out which is a 3000x2 matrix.
I tried
out<-out[out[,1] > out[,2]]
but this eliminates the row.names altogether, and I get a string of integers between 1 to 3000. Would there be a way to preserve the row.names?
Of note, if you only return a subset of one row to form a matrix with one dimension being unity, R will drop the row name:
m <- matrix(1:9, ncol = 3)
rownames(m) <- c("a", "b", "c")
m[1, ] # lost the row name
m[1, , drop = FALSE] # got row name back and a matrix
m[c(1,1), ] # the row name is back when result has nrow > 1
There appears to be no simple way of working around this other than checking for one-row result and assigning the row name.
A matrix is treated by R as a vector with columns and rows.
> A <- matrix(1:9, ncol=3)
# A is filled with 1,...,9 columnwise
> A
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
# only elements with even number in 2nd column of same row
> v <- A[A[,2] %% 2 == 0]
> m <- A[A[,2] %% 2 == 0,]
> v
[1] 1 3 4 6 7 9
> m
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 3 6 9
# The result of evaluating odd/even-ness of middle column.
# This boolean vector is repeated column-wise by default
# until all element's fate in A is determined.
> A[,2] %% 2 == 0
[1] TRUE FALSE TRUE
When you leave out the comma (v), then you address A as a 1-dimensional data structure and R implicitely handles your expression as a vector.
v is in that sense not "string of integers" but a vector of integers. When you add the comma, then you tell R that your condition only adresses the first dimension while indicating a second one (after the comma) - which causes R to handle your expression as a matrix (m).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
R and matrix with 1 row
I have hundreds of matrix and in a for loop I am doing some alterations on them including ordering them. The problem is with matrices which have only one row. So when I order them their class would change from matrix to character like below:
> test1
Gene ID Gene Name Score(d) Fold Change q-value(%)
[1,] "g17035" "17035" "-29.1" "0.877" "303.826"
> class(test1)
[1] "matrix"
and when applying the order it becomes character class:
test1 <- test1[order(test1[, 5]), ]
> test1
Gene ID Gene Name Score(d) Fold Change q-value(%)
"g17035" "17035" "-29.1" "0.877" "303.826"
> class(test1)
[1] "character"
I even used the as.matrix but it changes the matrix in an unwanted order:
test1 <-as.matrix( test1[order(test1[, 5]), ])
and then it would be like this:
> test1
[,1]
Gene ID "g17035"
Gene Name "17035"
Score(d) "-29.1"
Fold Change "0.877"
q-value(%) "303.826"
how can I fix it?
Thank you in advance
What you are looking for is to not reduce the dimension of the subset and the way to do it is with the drop argument to [. More info is available in ?"[".
# Demo matrix
> a <- matrix(1:9, 3, 3)
> a
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
# With reduction
> a[1,]
[1] 1 4 7
> class(a[1,])
[1] "integer"
# Without reduction
> a[1,,drop=FALSE]
[,1] [,2] [,3]
[1,] 1 4 7
> class(a[1,,drop=FALSE])
[1] "matrix"