为了账号安全,请及时绑定邮箱和手机立即绑定

`levels <-`(这是什么法术?

`levels <-`(这是什么法术?

ABOUTYOU 2019-10-06 12:55:47
在回答另一个问题时,@ Marek发布了以下解决方案:https ://stackoverflow.com/a/10432263/636656dat <- structure(list(product = c(11L, 11L, 9L, 9L, 6L, 1L, 11L, 5L,                                   7L, 11L, 5L, 11L, 4L, 3L, 10L, 7L, 10L, 5L, 9L, 8L)), .Names = "product", row.names = c(NA, -20L), class = "data.frame")`levels<-`(  factor(dat$product),  list(Tylenol=1:3, Advil=4:6, Bayer=7:9, Generic=10:12)  )产生的输出: [1] Generic Generic Bayer   Bayer   Advil   Tylenol Generic Advil   Bayer   Generic Advil   Generic Advil   Tylenol[15] Generic Bayer   Generic Advil   Bayer   Bayer  这只是矢量的打印输出,因此要存储它,您可能会更加困惑:res <- `levels<-`(  factor(dat$product),  list(Tylenol=1:3, Advil=4:6, Bayer=7:9, Generic=10:12)  )显然,这是对level函数的某种调用,但是我不知道在这里正在做什么。这种巫术的术语是什么,我如何在这方面增加我的魔法能力?
查看完整描述

3 回答

?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

这里的答案是好的,但是它们缺少重要的一点。让我尝试描述一下。


R是一种功能语言,不喜欢对其对象进行突变。但是它确实允许使用替换函数进行赋值语句:


levels(x) <- y

相当于


x <- `levels<-`(x, y)

诀窍是,这种重写是由<-; 完成的。它不是由levels<-。levels<-只是一个接受输入并给出输出的常规函数;它不会改变任何东西。


结果之一是,根据上述规则,<-必须是递归的:


levels(factor(x)) <- y


factor(x) <- `levels<-`(factor(x), y)


x <- `factor<-`(x, `levels<-`(factor(x), y))

这种纯功能的转换(直到最后,发生赋值)等同于一种命令式语言中的赋值,这是一种美丽。如果我没记错的话,这种用功能语言构造的镜头称为镜头。


但是,一旦您定义了诸如的替换函数levels<-,您将获得另一个意想不到的意外收获:您不仅具有进行分配的能力,还拥有一个方便的函数,该函数吸收了一个因数,并给出了另一个具有不同级别的因数。确实没有任何“分配”!


因此,您所描述的代码只是利用的另一种解释levels<-。我承认这个名称levels<-有点令人困惑,因为它暗示了一项任务,但是事实并非如此。该代码只是建立了一种管道:


从...开始 dat$product


将其转换为因子


改变水平


存放在 res


我个人认为代码行很漂亮;)


查看完整回答
反对 回复 2019-10-06
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

没有法宝,这就是(子)分配功能的定义方式。  levels<-有所不同,因为它是(子)分配因子属性而不是元素本身的原始函数。有很多此类函数的示例:


`<-`              # assignment

`[<-`             # sub-assignment

`[<-.data.frame`  # sub-assignment data.frame method

`dimnames<-`      # change dimname attribute

`attributes<-`    # change any attributes

其他二进制运算符也可以这样调用:


`+`(1,2)  # 3

`-`(1,2)  # -1

`*`(1,2)  # 2

`/`(1,2)  # 0.5

既然您知道了,类似这样的事情应该真的让您大吃一惊:


Data <- data.frame(x=1:10, y=10:1)

names(Data)[1] <- "HI"              # How does that work?!? Magic! ;-)


查看完整回答
反对 回复 2019-10-06
?
红颜莎娜

TA贡献1842条经验 获得超12个赞

之所以说是“魔术”,是因为“赋值”表格必须具有实际变量才能使用。而且factor(dat$product)没有分配任何东西。


# This works since its done in several steps

x <- factor(dat$product)

levels(x) <- list(Tylenol=1:3, Advil=4:6, Bayer=7:9, Generic=10:12)

x


# This doesn't work although it's the "same" thing:

levels(factor(dat$product)) <- list(Tylenol=1:3, Advil=4:6, Bayer=7:9, Generic=10:12)

# Error: could not find function "factor<-"


# and this is the magic work-around that does work

`levels<-`(

  factor(dat$product),

  list(Tylenol=1:3, Advil=4:6, Bayer=7:9, Generic=10:12)

  )


查看完整回答
反对 回复 2019-10-06
  • 3 回答
  • 0 关注
  • 781 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信