问题
I read these:
- https://stackoverflow.com/a/5159049/1175496
Matrices are for data of the same type.
- https://stackoverflow.com/q/29732279/1175496
Vectors (and so matrix) can accept only one type of data
If matrix can only accept one data type, why can I do this:
> m_list<-matrix(list('1',2,3,4),2,2)
> m_list
[,1] [,2]
[1,] "1" 3
[2,] 2 4
The console output looks like I am combining character and integer data types. The console output looks similar to this matrix:
> m_vector<-matrix(1:4,2,2)
> m_vector
[,1] [,2]
[1,] 1 3
[2,] 2 4
When I assign to m_list, it doesn't coerce the other values (as in https://stackoverflow.com/q/29732279/1175496 )
> m_list[2,2] <-'4'
> m_list
[,1] [,2]
[1,] "1" 3
[2,] 2 "4"
回答1:
OK here is what I gather from replies so far:
Question
How can I have a matrix with different types?
Answer
You cannot; the elements are not different types; all (4) elements of this matrix are lists
all(
is.list(m_list[1,1]),
is.list(m_list[2,1]),
is.list(m_list[1,2]),
is.list(m_list[2,2]))
#[1] TRUE
Question
But I constructed matrix like this: matrix(list('1',2,3,4),2,2)
, how did this become a matrix of (4) lists, rather than a matrix of (4) characters, or even (4) integers?
Answer
I'm not sure. Even though the documentation says re: the first argument to matrix:
Non-atomic classed R objects are coerced by as.vector and all attributes discarded.
It seems these are identical
identical(as.vector(list('1',2,3,4)), list('1',2,3,4))
#[1] TRUE
Question
But I assign a character ('4'
) to an element of m_list
, how does that work?
m_list[2,2] <-'4'
Answer
It is "coerced", as if you did this:
m_list[2,2] <- as.list('4')
Question
If the elements in m_list
are lists, is m_list equivalent to matrix(c(list('1'),list(2),list(3),list(4)),2,2)
?
Answer
Yes, these are equivalent:
m_list <- matrix(list('1',2,3,4),2,2)
m_list2 <- matrix(c(list('1'),list(2),list(3),list(4)),2,2)
identical(m_list, m_list2)
#[1] TRUE
Question
So how can I retrieve the typeof
the '1'
hidden in m_list[1,1]
?
Answer
At least two ways:
typeof(m_list[1,1][[1]])
#[1] "character"
...or, can directly do this (thanks, Frank) (since indexing has this "is applied in turn to the list, the selected component, the selected component of that component, and so on" behavior)...
typeof(m_list[[1,1]])
#[1] "character"
Question
How can I tell the difference between these two
m1 <- matrix(c(list(1), list(2), list(3), list(4)), 2, 2)
m2 <- matrix(1:4, 2, 2)
Answer
If you are using RStudio,
- m1 is described as
List of 4
- m2 is described as
int [1:2, 1:2] 1 2 3 4
..or else, just use typeof(), which for vectors and matrices, identifies the type of their elements... (thanks, Martin)
typeof(m1)
#[1] "list"
typeof(m2)
#[1] "integer"
class
can also help distinguish, but you must wrap the matrices in vectors first:
#Without c(...)
class(m1)
#[1] "matrix"
class(m2)
#[1] "matrix"
#With c(...)
class(c(m1))
#[1] "list"
class(c(m2))
#[1] "integer"
...you could tell a subtle difference in the console output; notice how the m2 (containing integers) right-aligns its elements (because numerics are usually right-aligned)...
m1
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
m2
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
回答2:
Picking up the comments, verify yourself:
typeof(m_list)
typeof(m_list[2,2])
来源:https://stackoverflow.com/questions/33352746/can-an-r-matrix-contain-different-datatypes-does-this-hacked-up-matrix-of-lists