热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

我们可以在R中得到因子矩阵吗?

如何解决《我们可以在R中得到因子矩阵吗?》经验,为你挑选了2个好方法。

似乎不可能在R中得到因子矩阵.这是真的吗?如果是,为什么?如果没有,我该怎么办?

f <- factor(sample(letters[1:5], 20, rep=TRUE), letters[1:5])
m <- matrix(f,4,5)
is.factor(m) # fail.

m <- factor(m,letters[1:5])
is.factor(m) # oh, yes? 
is.matrix(m) # nope. fail. 

dim(f) <- c(4,5) # aha?
is.factor(f) # yes.. 
is.matrix(f) # yes!

# but then I get a strange behavior
cbind(f,f) # is not a factor anymore
head(f,2) # doesn't give the first 2 rows but the first 2 elements of f
# should I worry about it?

Reinstate Mo.. 20

在这种情况下,它可能像鸭子一样走路,甚至像鸭子一样嘎嘎叫,但f来自:

f <- factor(sample(letters[1:5], 20, rep=TRUE), letters[1:5])
dim(f) <- c(4,5)

真的不是一个矩阵,即使is.matrix()声称它严格是一个矩阵.就所is.matrix()涉及的矩阵而言,f只需要是一个向量并具有一个dim属性.通过添加属性给f您通过测试.然而,正如您所看到的,一旦您开始使用f矩阵,它很快就会失去使其成为一个因素的功能(您最终会使用级别或维度丢失).

实际上只有原子向量类型的矩阵和数组:

    合乎逻辑的,

    整数,

    真实,

    复杂,

    字符串(或字符),和

    生的

另外,正如@hadley提醒我的那样,你也可以有列表矩阵和数组(通过dim在列表对象上设置属性.例如,参见Hadley的书,Advanced R的Matrices&Arrays部分.)

任何超出这些类型的东西都会被强制转换为某种较低类型的东西as.vector().这发生在matrix(f, nrow = 3)不是因为f是原子根据 is.atomic()(它返回TRUEf,因为它在内部存储为一个整数和typeof(f)返回"integer"),但因为它具有class属性.这将设置OBJECT内部表示的位,f并且任何具有类的内容都应该通过以下方式强制转换为其中一种原子类型as.vector():

matrix <- function(data = NA, nrow = 1, ncol = 1, byrow = FALSE,
                   dimnames = NULL) {
    if (is.object(data) || !is.atomic(data)) 
        data <- as.vector(data)
....

通过添加维度dim<-()是一种快速创建数组而无需复制对象的方法,但这会绕过R f通过其他方法强制转换为矩阵时所做的一些检查和平衡

matrix(f, nrow = 3) # or
as.matrix(f)

当您尝试使用在矩阵上工作的基本函数或使用方法分派时,会发现这一点.请注意,在分配尺寸后f,f仍然是类"factor":

> class(f)
[1] "factor"

这解释了head()行为; 你没有得到这个head.matrix行为,因为f它不是一个矩阵,至少就S3机制而言:

> debug(head.matrix)
> head(f) # we don't enter the debugger
[1] d c a d b d
Levels: a b c d e
> undebug(head.matrix)

并且head.default方法调用[有一个factor方法,因此观察到的行为:

> debugonce(`[.factor`)
> head(f)
debugging in: `[.factor`(x, seq_len(n))
debug: {
    y <- NextMethod("[")
    attr(y, "contrasts") <- attr(x, "contrasts")
    attr(y, "levels") <- attr(x, "levels")
    class(y) <- oldClass(x)
    lev <- levels(x)
    if (drop) 
        factor(y, exclude = if (anyNA(levels(x))) 
            NULL
        else NA)
    else y
}
....

cbind()行为可以从(从记录的行为进行解释?cbind,重点煤矿):

功能cbindrbindS3通用,...

....

在默认方法中,所有向量/矩阵必须是原子(参见vector)或列表.表达是不允许的.语言对象(例如公式和调用)和pairlists将被强制转换为列表:其他对象(如名称和外部指针)将作为元素包含在列表结果中. 输入可能具有的任何类都被丢弃(特别是,因子被其内部代码替换).

同样,这其实f是阶级的"factor"是打败你,因为默认的cbind方法被调用,它将剥离水平的信息,当你观察到的返回内部整数代码.

在许多方面,你必须忽略或至少不完全信任is.foo函数告诉你的内容,因为它们只是使用简单的测试来说明某些东西是否是某个foo对象.is.matrix()is.atomic()是显然是错误的,当涉及到f(用尺寸)从一个特定点.它们在实施方面也是正确的,或者至少可以从实施中理解它们的行为; 我认为is.atomic(f)是不正确的,但如果用"如果是一个原子类型的" [R核心意思是"型"是由返回的东西typeof(f),然后is.atomic()是正确的.更严格的测试is.vector(),它f失败:

> is.vector(f)
[1] FALSE

因为它具有超出names属性的属性:

> attributes(f)
$levels
[1] "a" "b" "c" "d" "e"

$class
[1] "factor"

$dim
[1] 4 5

至于你应该如何获得因子矩阵,至少如果你想要它保留因子信息(水平的标签),你就不能.一种解决方案是使用字符矩阵,它将保留标签:

> fl <- levels(f)
> fm <- matrix(f, ncol = 5)
> fm
     [,1] [,2] [,3] [,4] [,5]
[1,] "c"  "a"  "a"  "c"  "b" 
[2,] "d"  "b"  "d"  "b"  "a" 
[3,] "e"  "e"  "e"  "c"  "e" 
[4,] "a"  "b"  "b"  "a"  "e"

并且我们存储f未来使用的级别,因为我们在此过程中会丢失一些矩阵元素.

或者使用内部整数表示:

> (fm2 <- matrix(unclass(f), ncol = 5))
     [,1] [,2] [,3] [,4] [,5]
[1,]    3    1    1    3    2
[2,]    4    2    4    2    1
[3,]    5    5    5    3    5
[4,]    1    2    2    1    5

并且您可以通过以下方式再次返回级别/标签:

> fm2[] <- fl[fm2]
> fm2
     [,1] [,2] [,3] [,4] [,5]
[1,] "c"  "a"  "a"  "c"  "b" 
[2,] "d"  "b"  "d"  "b"  "a" 
[3,] "e"  "e"  "e"  "c"  "e" 
[4,] "a"  "b"  "b"  "a"  "e"

使用数据框似乎并不理想,因为数据框的每个组件都将被视为一个单独的因素,而您似乎希望将数组视为具有一组级别的单个因子.

如果你真的想做你想要的,有一个因子矩阵,你很可能需要创建自己的S3类来完成这个,加上所有的方法.例如,您可以将因子矩阵存储为字符矩阵但"factorMatrix"存储类,其中您将级别存储在因子矩阵旁边作为额外属性.然后你需要编写[.factorMatrix,这将获取级别,然后使用[矩阵上的默认方法,然后再次添加级别属性.你也可以写cbindhead方法.然而,所需方法的列表会快速增长,但是一个简单的实现可能适合,如果你让你的对象有类c("factorMatrix", "matrix")(即继承自"matrix"类),你将获取该类的所有属性/方法"matrix"(这将删除级别和其他属性)因此您至少可以使用这些对象,并查看您需要添加新方法以填写类的行为.



1> Reinstate Mo..:

在这种情况下,它可能像鸭子一样走路,甚至像鸭子一样嘎嘎叫,但f来自:

f <- factor(sample(letters[1:5], 20, rep=TRUE), letters[1:5])
dim(f) <- c(4,5)

真的不是一个矩阵,即使is.matrix()声称它严格是一个矩阵.就所is.matrix()涉及的矩阵而言,f只需要是一个向量并具有一个dim属性.通过添加属性给f您通过测试.然而,正如您所看到的,一旦您开始使用f矩阵,它很快就会失去使其成为一个因素的功能(您最终会使用级别或维度丢失).

实际上只有原子向量类型的矩阵和数组:

    合乎逻辑的,

    整数,

    真实,

    复杂,

    字符串(或字符),和

    生的

另外,正如@hadley提醒我的那样,你也可以有列表矩阵和数组(通过dim在列表对象上设置属性.例如,参见Hadley的书,Advanced R的Matrices&Arrays部分.)

任何超出这些类型的东西都会被强制转换为某种较低类型的东西as.vector().这发生在matrix(f, nrow = 3)不是因为f是原子根据 is.atomic()(它返回TRUEf,因为它在内部存储为一个整数和typeof(f)返回"integer"),但因为它具有class属性.这将设置OBJECT内部表示的位,f并且任何具有类的内容都应该通过以下方式强制转换为其中一种原子类型as.vector():

matrix <- function(data = NA, nrow = 1, ncol = 1, byrow = FALSE,
                   dimnames = NULL) {
    if (is.object(data) || !is.atomic(data)) 
        data <- as.vector(data)
....

通过添加维度dim<-()是一种快速创建数组而无需复制对象的方法,但这会绕过R f通过其他方法强制转换为矩阵时所做的一些检查和平衡

matrix(f, nrow = 3) # or
as.matrix(f)

当您尝试使用在矩阵上工作的基本函数或使用方法分派时,会发现这一点.请注意,在分配尺寸后f,f仍然是类"factor":

> class(f)
[1] "factor"

这解释了head()行为; 你没有得到这个head.matrix行为,因为f它不是一个矩阵,至少就S3机制而言:

> debug(head.matrix)
> head(f) # we don't enter the debugger
[1] d c a d b d
Levels: a b c d e
> undebug(head.matrix)

并且head.default方法调用[有一个factor方法,因此观察到的行为:

> debugonce(`[.factor`)
> head(f)
debugging in: `[.factor`(x, seq_len(n))
debug: {
    y <- NextMethod("[")
    attr(y, "contrasts") <- attr(x, "contrasts")
    attr(y, "levels") <- attr(x, "levels")
    class(y) <- oldClass(x)
    lev <- levels(x)
    if (drop) 
        factor(y, exclude = if (anyNA(levels(x))) 
            NULL
        else NA)
    else y
}
....

cbind()行为可以从(从记录的行为进行解释?cbind,重点煤矿):

功能cbindrbindS3通用,...

....

在默认方法中,所有向量/矩阵必须是原子(参见vector)或列表.表达是不允许的.语言对象(例如公式和调用)和pairlists将被强制转换为列表:其他对象(如名称和外部指针)将作为元素包含在列表结果中. 输入可能具有的任何类都被丢弃(特别是,因子被其内部代码替换).

同样,这其实f是阶级的"factor"是打败你,因为默认的cbind方法被调用,它将剥离水平的信息,当你观察到的返回内部整数代码.

在许多方面,你必须忽略或至少不完全信任is.foo函数告诉你的内容,因为它们只是使用简单的测试来说明某些东西是否是某个foo对象.is.matrix()is.atomic()是显然是错误的,当涉及到f(用尺寸)从一个特定点.它们在实施方面也是正确的,或者至少可以从实施中理解它们的行为; 我认为is.atomic(f)是不正确的,但如果用"如果是一个原子类型的" [R核心意思是"型"是由返回的东西typeof(f),然后is.atomic()是正确的.更严格的测试is.vector(),它f失败:

> is.vector(f)
[1] FALSE

因为它具有超出names属性的属性:

> attributes(f)
$levels
[1] "a" "b" "c" "d" "e"

$class
[1] "factor"

$dim
[1] 4 5

至于你应该如何获得因子矩阵,至少如果你想要它保留因子信息(水平的标签),你就不能.一种解决方案是使用字符矩阵,它将保留标签:

> fl <- levels(f)
> fm <- matrix(f, ncol = 5)
> fm
     [,1] [,2] [,3] [,4] [,5]
[1,] "c"  "a"  "a"  "c"  "b" 
[2,] "d"  "b"  "d"  "b"  "a" 
[3,] "e"  "e"  "e"  "c"  "e" 
[4,] "a"  "b"  "b"  "a"  "e"

并且我们存储f未来使用的级别,因为我们在此过程中会丢失一些矩阵元素.

或者使用内部整数表示:

> (fm2 <- matrix(unclass(f), ncol = 5))
     [,1] [,2] [,3] [,4] [,5]
[1,]    3    1    1    3    2
[2,]    4    2    4    2    1
[3,]    5    5    5    3    5
[4,]    1    2    2    1    5

并且您可以通过以下方式再次返回级别/标签:

> fm2[] <- fl[fm2]
> fm2
     [,1] [,2] [,3] [,4] [,5]
[1,] "c"  "a"  "a"  "c"  "b" 
[2,] "d"  "b"  "d"  "b"  "a" 
[3,] "e"  "e"  "e"  "c"  "e" 
[4,] "a"  "b"  "b"  "a"  "e"

使用数据框似乎并不理想,因为数据框的每个组件都将被视为一个单独的因素,而您似乎希望将数组视为具有一组级别的单个因子.

如果你真的想做你想要的,有一个因子矩阵,你很可能需要创建自己的S3类来完成这个,加上所有的方法.例如,您可以将因子矩阵存储为字符矩阵但"factorMatrix"存储类,其中您将级别存储在因子矩阵旁边作为额外属性.然后你需要编写[.factorMatrix,这将获取级别,然后使用[矩阵上的默认方法,然后再次添加级别属性.你也可以写cbindhead方法.然而,所需方法的列表会快速增长,但是一个简单的实现可能适合,如果你让你的对象有类c("factorMatrix", "matrix")(即继承自"matrix"类),你将获取该类的所有属性/方法"matrix"(这将删除级别和其他属性)因此您至少可以使用这些对象,并查看您需要添加新方法以填写类的行为.



2> BrodieG..:

不幸的是,因子支持在R中并不完全通用,因此许多R函数默认将因子视为其内部存储类型,即integer:

> typeof(factor(letters[1:3]))
[1] "integer  

这是发生的事情matrix,cbind.他们不知道如何处理因子,但他们确实知道如何处理整数,因此他们将你的因子视为整数. head实际上恰恰相反.它确实知道如何处理一个因子,但它从来不会检查你的因子也是一个矩阵,所以只需将它视为一个普通的无量纲因子向量.

你最好的操作就好像你的矩阵有因素一样,就是强迫它去角色.完成操作后,可以将其恢复为因子形式.您也可以使用整数形式执行此操作,但是您可能会遇到奇怪的事情(例如,您可以对整数矩阵进行矩阵乘法,但这对因子没有意义).

请注意,如果您将"矩阵"类添加到您的因子中,则某些(但不是全部)事情开始起作用:

f <- factor(letters[1:9])
dim(f) <- c(3, 3)
class(f) <- c("factor", "matrix")
head(f, 2)

生产:

     [,1] [,2] [,3]
[1,] a    d    g   
[2,] b    e    h   
Levels: a b c d e f g h i

这不能解决rbind等问题.


推荐阅读
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文介绍了在iOS开发中使用UITextField实现字符限制的方法,包括利用代理方法和使用BNTextField-Limit库的实现策略。通过这些方法,开发者可以方便地限制UITextField的字符个数和输入规则。 ... [详细]
  • 接下来要动手来做一个组件了,我想了一个计数器组件,功能方面是比较简单的,但这不是本章的重点,这一章的重点是说明一个组件的制作全过程。在其中可以学到很多组件制作的技巧,当然这些也是我从书上学得的。 ... [详细]
author-avatar
FEEL欧诺_625
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有