如何从另一个data.table重命名R data.table中的级别?

Sev*_*eux 2 r data.table

我有两个data.tables,dt是一个长整数列levels,其整数列的范围为1 ... 5,另一个是data.table“ labels”,其中包含简单形式的标签,例如:

labels <- data.table(V1=1:5, V2=c("Very Low", "Low", "Median", "High", "Very High"))
#    V1       V2
# 1:  1       Very Low
# 2:  2       Low
# 3:  3       Median
# 4:  4       High
# 5:  5       Very High
Run Code Online (Sandbox Code Playgroud)

实际dt值相当大,但是对于可重现性而言,一个简单的方法就可以做到(尽管在实际DT级别中不是那么规则):

dt <- data.table(levels=rep(1:5, times=10))
Run Code Online (Sandbox Code Playgroud)

如何一次性dt用字符标签替换级别列labels

我可以在手动循环中执行此操作(丑陋!),也可以通过添加另一列来执行此操作,如下所示:

dt[, tmp := labels$V2[dt$level] ]
Run Code Online (Sandbox Code Playgroud)

然后删除列level并重命名tmp

有没有一种好的data.table方法来做到这一点?

Jaa*_*aap 5

最简单的方法是加入data.tables。为了显示效果,我在其中添加了一个iddt(见下文)。您可以按以下方式加入data.tables

dt[labels, on=c("levels"="V1")][order(id)] # the [order(id)] part is not necessary, but added to show the effect better
Run Code Online (Sandbox Code Playgroud)

给出(前7行):

    levels id        V2
 1:      1  1  Very Low
 2:      2  2       Low
 3:      3  3    Median
 4:      4  4      High
 5:      5  5 Very High
 6:      1  6  Very Low
 7:      2  7       Low
....
Run Code Online (Sandbox Code Playgroud)

甚至可能更好:

dt <- dt[labels, .(id,levels=V2), on=c("levels"="V1")][order(id)]
Run Code Online (Sandbox Code Playgroud)

给出(前7行):

> dt
    id    levels
 1:  1  Very Low
 2:  2       Low
 3:  3    Median
 4:  4      High
 5:  5 Very High
 6:  6  Very Low
 7:  7       Low
....
Run Code Online (Sandbox Code Playgroud)

另一种选择是将match函数与labels data.table一起用作查找表:

dt[, levels := labels$V2[match(levels, labels$V1)]]
Run Code Online (Sandbox Code Playgroud)

这使:

> dt
       levels id
 1:  Very Low  1
 2:       Low  2
 3:    Median  3
 4:      High  4
 5: Very High  5
 6:  Very Low  6
 7:       Low  7
....
Run Code Online (Sandbox Code Playgroud)

使用的数据:

dt <- data.table(levels=rep(1:5, times=10))[,id:=.I]
labels <- data.table(V1=1:5, V2=c("Very Low", "Low", "Median", "High", "Very High"))
Run Code Online (Sandbox Code Playgroud)