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

在回答另一个问题时,@ Marek发布了以下解决方案:https ://stackoverflow.com/a/10432263/636656


dat <- 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函数的某种调用,但是我不知道在这里正在做什么。这种巫术的术语是什么,我如何在这方面增加我的魔法能力?


ABOUTYOU
浏览 788回答 3
3回答

潇潇雨雨

这里的答案是好的,但是它们缺少重要的一点。让我尝试描述一下。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我个人认为代码行很漂亮;)

慕虎7371278

没有法宝,这就是(子)分配功能的定义方式。&nbsp; levels<-有所不同,因为它是(子)分配因子属性而不是元素本身的原始函数。有很多此类函数的示例:`<-`&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # assignment`[<-`&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# sub-assignment`[<-.data.frame`&nbsp; # sub-assignment data.frame method`dimnames<-`&nbsp; &nbsp; &nbsp; # change dimname attribute`attributes<-`&nbsp; &nbsp; # change any attributes其他二进制运算符也可以这样调用:`+`(1,2)&nbsp; # 3`-`(1,2)&nbsp; # -1`*`(1,2)&nbsp; # 2`/`(1,2)&nbsp; # 0.5既然您知道了,类似这样的事情应该真的让您大吃一惊:Data <- data.frame(x=1:10, y=10:1)names(Data)[1] <- "HI"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # How does that work?!? Magic! ;-)

红颜莎娜

之所以说是“魔术”,是因为“赋值”表格必须具有实际变量才能使用。而且factor(dat$product)没有分配任何东西。# This works since its done in several stepsx <- 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<-`(&nbsp; factor(dat$product),&nbsp; list(Tylenol=1:3, Advil=4:6, Bayer=7:9, Generic=10:12)&nbsp; )
打开App,查看更多内容
随时随地看视频慕课网APP