R 如何更改data.table中因子列的级别
更改R 如何更改data.table中因子列的级别,r,data.table,R,Data.table,更改数据表中系数列的级别的正确方法是什么(注意:不是数据框) 您仍然可以按传统方式设置它们: levels(mydt$value) <- c(...) 但是一定要指定一个有效的级别向量(输入足够长的字符),否则你会得到一个无效的因子(级别),你也可以使用相关的方法重命名并添加到级别,这非常方便,特别是如果你正在绘制一个需要以特定顺序提供更多信息的标签的图(与默认情况相反): f我宁愿采用传统的方式重新分配因子 >mydt$value#这是我们最初拥有的 [1] A B B C 级别:A、
数据表中系数
列的级别的正确方法是什么(注意:不是数据框)
您仍然可以按传统方式设置它们:
levels(mydt$value) <- c(...)
但是一定要指定一个有效的级别向量(输入足够长的字符
),否则你会得到一个无效的因子(级别),你也可以使用相关的方法重命名并添加到级别,这非常方便,特别是如果你正在绘制一个需要以特定顺序提供更多信息的标签的图(与默认情况相反):
f我宁愿采用传统的方式重新分配因子
>mydt$value#这是我们最初拥有的
[1] A B B C
级别:A、B、C
>级别(mydt$值)#只需检查级别
[1] “A”“B”“C”
**#重新分配的任务**
>级别(mydt$值)[级别(mydt$值)=“A”]级别(mydt$值)[级别(mydt$值)=“B”]级别(mydt$值)[级别(mydt$值)=“C”]级别(mydt$值)
[1] “X”“Y”“Z”
>mydt#这是我们想要的
id值
1:1 X
2:2x
3:3岁
4:4 Y
5:5岁
6:6 Z
正如您可能注意到的,重新分配的内容非常直观,它检查确切的级别(如果存在模糊数学、正则表达式或类似情况,请使用grepl
)
levels(mydt$value)[levels(mydt$value)=“A”]更改列级别的最简单方法:
dat$colname这比Matt Dowle的建议更安全(因为它使用setattr跳过的检查),但不会复制整个data.table。它将替换整个列向量(而Matt的解决方案仅替换列向量的属性),但这似乎是一个可以接受的权衡,以减少弄乱因子对象的风险
mydt[, value:=`levels<-`(value, c("X", "Y", "Z"))]
mydt[,value:=`levels您仍然可以按传统方式设置它们:levels(mydt$value)我没有尝试明显的:)谢谢!把它作为一个答案,这样我就可以接受了?+1严格来说,问题是当系数是数据的一列时如何更改级别。table
数据。table
内置了允许通过引用添加和重命名系数的功能,以避免为了速度而复制整个对象。:=
在系数列上,如果RHS不存在,将自动将其添加为级别。并且可以使用setattr
通过引用更改系数列的级别(无副本)@MatthewDowle啊,你知道我甚至没有捕捉到数据。table
与数据。frame
!谢谢你指出这一点。我的大多数数据集的大小都很小,但我知道数据。table
还有一些我知道可以使用的很好的功能。@MatthewDowle谢谢你的提醒。setattr
正是我想要的king for。我已经将它包装在一个带有错误检查的函数中:@RicardoSaporta看起来很棒。也许我可以将它添加到data.table?我将它命名为setlevels
,并稍微更改接口:setlevels(DT$colname,newlevels)
,如果可以的话?人们经常要求set*
函数处理data.frame
,他们也可以这样做。@MattDowle,didsetlevels()
get-put-in-end?我找不到关于它的任何其他文档。@MattDowle如果我想同时在多个列上使用相同的级别怎么办?有什么快捷方式吗?@skan看起来像setlevels()
在C级别内部存在,但从未公开过。我只是在这里指了指。如果你想添加它,拉请求将非常受欢迎。同时可以使用setattr
。要将相同级别分配给多个列,我认为for
循环对于未来的cod读者来说是最好、最快速、最清晰的e、 提供了一个set*
函数在循环内部使用,以避免复制。但是这一部分的每一行都将复制整个mydt
。如果mydt
在RAM中是20GB,那就是60GB,它将进行翻滚。数据。表
用于提高内存效率以及语法。贾斯汀的回答完全不复制20GB,我认为t只是直接在适当的位置更改级别。这里所表达的有效问题的答案是将这种良好的逻辑封装到新函数setlevels
,它在精神上类似于setnames
@MattDowle的安全性、健壮性和直观性。谢谢您提到这一点。您能提到哪一个级别吗s(mydt$value)[levels(mydt$value)=“A”]即使你只触摸了mydt
的一小部分,当你使用@MattDowle时,R也会复制整个mydt
。非常感谢你在两个笔记上的详细解释+1。我现在也“准确地”理解Justin的评论。我一直在寻找这一行永远的LOL级别(mydt$value)[级别(mydt$value)=“A”]
# 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
levels(mydt$value) <- c(...)
setattr(mydt$value,"levels",c(...))
f <- factor(c("a","b"))
levels(f) <- list(C = "C", D = "a", B = "b")
> 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
mydt[, value:=`levels<-`(value, c("X", "Y", "Z"))]