【问题标题】:Can an R matrix contain different datatypes? Does this hacked-up matrix-of-lists work?R 矩阵可以包含不同的数据类型吗?这个黑掉的列表矩阵有用吗?
【发布时间】:2016-01-25 23:10:12
【问题描述】:

我读过这些:

如果矩阵只能接受一种数据类型,我为什么要这样做:

> m_list<-matrix(list('1',2,3,4),2,2)
> m_list
     [,1] [,2]
[1,] "1"  3   
[2,] 2    4   

控制台输出看起来像是在组合字符和整数数据类型。 控制台输出类似于此矩阵:

> m_vector<-matrix(1:4,2,2)
> m_vector
     [,1] [,2]
[1,]   1    3   
[2,]   2    4   

当我分配给 m_list 时,它不会强制其他值(如在 https://stackoverflow.com/q/29732279/1175496 中)

> m_list[2,2] <-'4'
> m_list
     [,1] [,2]
[1,] "1"  3 
[2,] 2    "4"  

【问题讨论】:

  • 是的,这里的矩阵还是一个类型/模式单一的向量。试试?vector 看看向量的类型。
  • 我认为将矩阵保留为一种类型通常是个好主意(例如纯numeric)。但是,我会对以这种方式使用矩阵 (list) 对计算性能的影响感兴趣;虽然最有力的论据可能是事情不会变得混乱......
  • 如果您想要精确的定义,我建议您阅读 ?matrix 而不是 SO。
  • 如果您想要一个具有不同数据类型的矩阵,请使用数据框 (/data.table/ tibble)(不要像这样破坏列表矩阵,它会在任何重要的操作上失败)。

标签: r list matrix types


【解决方案1】:

好的,这是我迄今为止从回复中收集到的:

问题

我怎样才能拥有不同类型的矩阵?

回答

你不能;元素不是不同的类型;该矩阵的所有 (4) 个元素都是列表

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

问题

但是我构造了这样的矩阵:matrix(list('1',2,3,4),2,2),这怎么变成了(4)个列表的矩阵,而不是(4)个字符的矩阵,甚至 (4) 个整数

回答

我不确定。即使文档说 re: the first argument to matrix:

非原子分类的 R 对象被 as.vector 和所有 属性被丢弃。

好像是一样的

identical(as.vector(list('1',2,3,4)), list('1',2,3,4))
#[1] TRUE

问题

但是我将一个字符 ('4') 分配给 m_list 的一个元素,它是如何工作的?

m_list[2,2] <-'4'

回答

它是“强制”的,就好像你这样做了:

m_list[2,2] <- as.list('4')

问题

如果m_list中的元素是列表,m_list是否等同于matrix(c(list('1'),list(2),list(3),list(4)),2,2)

回答

是的,这些是等价的:

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

问题

那么我怎样才能找回隐藏在m_list[1,1]中的typeof'1'呢?

回答

至少有两种方式:

typeof(m_list[1,1][[1]])
#[1] "character"

...或者,可以直接执行此操作(谢谢,Frank)(因为索引具有这种"is applied in turn to the list, the selected component, the selected component of that component, and so on" 行为)...

typeof(m_list[[1,1]])
#[1] "character"

问题

如何区分这两者

m1 <- matrix(c(list(1), list(2), list(3), list(4)), 2, 2)
m2 <- matrix(1:4, 2, 2)

回答

如果你使用的是 RStudio,

  • m1 被描述为List of 4
  • m2 被描述为int [1:2, 1:2] 1 2 3 4

..否则,只需使用 typeof(),它用于向量和矩阵,识别其元素的类型... (谢谢,Martin)

typeof(m1)
#[1] "list"
typeof(m2)
#[1] "integer"

class 也可以帮助区分,但必须先将矩阵包裹在向量中:

#Without c(...)
class(m1)
#[1] "matrix"
class(m2)
#[1] "matrix"
#With c(...)
class(c(m1))
#[1] "list"
class(c(m2))
#[1] "integer"

...您可以分辨出控制台输出的细微差别;注意 m2(包含整数)如何右对齐其元素(因为数字通常是右对齐的)...

m1
#     [,1] [,2]
#[1,] 1    3   
#[2,] 2    4   
m2
#     [,1] [,2]
#[1,]    1    3
#[2,]    2    4

【讨论】:

  • 很好的研究和答案。这里的标准是去掉以行开头的&gt;+ 并注释掉输出,这样就很容易复制粘贴代码并尝试一下。我发现typeof 不是检查 R 中对象的最佳方法;它主要是关于存储类型,而不是 R 类/类型。我建议class(c(m1)) 等。
  • 谢谢弗兰克。将来我将避免使用“>”,以便用户可以复制粘贴。而且我也感觉到classtypeof 更符合我的问题;后者是存储相关的
  • 弗兰克,我在我的编辑中加入了你的 cmets——但我仍然很难理解为什么matrix(list('1',2,3,4),2,2) 变成了一个矩阵,其中每个 item 都是一个列表?好像列表类被“分配”到了其中的每个元素?
  • 好问题。实际上,那里的每个项目不是 listm = matrix(list('1',2,3,4),2,2); sapply(m, class)。与mm = matrix(list(list('1'),list(2),list(3),list(4)),2,2); sapply(mm, class) 比较。请注意,后者是使用list 构造的,与您使用c 的示例不同。我想你以为 c(list(1), list(2)) 会像 list(list(1),list(2)),但实际上就像 list(1,2)
  • 哎呀,所以事情比我想象的要复杂。哦,好吧,我希望这可以帮助像我这样困惑的人:)
【解决方案2】:

拿起cmets,验证自己:

typeof(m_list)
typeof(m_list[2,2])

【讨论】:

  • 也值得一看typeof(m_list[[2,2]])
猜你喜欢
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
  • 2015-07-20
  • 2021-07-28
  • 1970-01-01
  • 1970-01-01
  • 2020-04-20
  • 1970-01-01
相关资源
最近更新 更多