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
我個人認為代碼行很漂亮;)

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! ;-)

TA貢獻1842條經驗 獲得超13個贊
之所以說是“魔術”,是因為“賦值”表格必須具有實際變量才能使用。而且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)
)
- 3 回答
- 0 關注
- 861 瀏覽
添加回答
舉報