Ric*_*rta 48 r data.table
更改a中factor
列的级别的正确方法是什么data.table
(注意:不是数据框)
library(data.table)
mydt <- data.table(id=1:6, value=as.factor(c("A", "A", "B", "B", "B", "C")), key="id")
mydt[, levels(value)]
[1] "A" "B" "C"
Run Code Online (Sandbox Code Playgroud)
我正在寻找类似的东西:
mydt[, levels(value) <- c("X", "Y", "Z")]
Run Code Online (Sandbox Code Playgroud)
但是,当然,上述行不起作用.
# Actual # Expected result
> mydt > mydt
id value id value
1: 1 A 1: 1 X
2: 2 A 2: 2 X
3: 3 B 3: 3 Y
4: 4 B 4: 4 Y
5: 5 B 5: 5 Y
6: 6 C 6: 6 Z
Run Code Online (Sandbox Code Playgroud)
Jus*_*tin 61
你仍然可以用传统方式设置它们:
levels(mydt$value) <- c(...)
Run Code Online (Sandbox Code Playgroud)
这应该足够快,除非mydt
非常大,因为传统语法复制整个对象.你也可以玩非保理和重构游戏......但无论如何也没有人喜欢那个游戏.
要通过引用更改级别而不复制以下内容mydt
:
setattr(mydt$value,"levels",c(...))
Run Code Online (Sandbox Code Playgroud)
但一定要指定一个有效的水平向量(character
足够长度的类型),否则你最终会得到一个无效因素(levels<-
做一些检查以及复制).
我宁愿采用传统的重新分配方式来考虑因素
> mydt$value # This we what we had originally
[1] A A B B B C
Levels: A B C
> levels(mydt$value) # just checking the levels
[1] "A" "B" "C"
**# Meat of the re-assignment**
> levels(mydt$value)[levels(mydt$value)=="A"] <- "X"
> levels(mydt$value)[levels(mydt$value)=="B"] <- "Y"
> levels(mydt$value)[levels(mydt$value)=="C"] <- "Z"
> levels(mydt$value)
[1] "X" "Y" "Z"
> mydt # This is what we wanted
id value
1: 1 X
2: 2 X
3: 3 Y
4: 4 Y
5: 5 Y
6: 6 Z
Run Code Online (Sandbox Code Playgroud)
您可能已经注意到,重新分配的内容非常直观,它检查是否正确level
(grepl
以防出现模糊数学,正则表达式或类似情况)
levels(mydt$value)[levels(mydt$value)=="A"] <- "X"
这会明确检查所 考虑变量的值,levels
然后将其重新分配X
(依此类推)-优势-您明确知道标记了什么的内容。
我发现重命名级别是levels(mydt$value) <- c("X","Y","Z")
非常不直观的,因为它只是将其分配X
给数据中的SEES的第一个级别(因此顺序确实很重要)
PPS:如果级别过多,请使用循环结构。
您还可以使用相关方法重命名并添加到级别中,这非常方便,特别是如果您正在制作需要按特定顺序(而不是默认顺序)提供更多信息的标签的绘图:
f <- factor(c("a","b"))
levels(f) <- list(C = "C", D = "a", B = "b")
Run Code Online (Sandbox Code Playgroud)
(修改自?levels
)