r-通过data.table从另一个表更新因子水平



我想从另一个更新表中非数字列的因子级别

以下是我尝试过的;

set.seed(1453)
library(data.table)
bigger_table <- data.table(region = paste0(rep('region_',50),sample(1:4,50,replace=T)),
factor_column = factor(sample(LETTERS[1:3],50,replace=T)),
numeric_column = rnorm(50,20,2))

subset_table <- bigger_table[region=='region_1']
nonnumeric_column <- names(bigger_table)[sapply(bigger_table,function(x) !is.numeric(x))]

subset_table[,(nonnumeric_column) := lapply(.SD,function(x) factor(x,levels = unique(bigger_table[,x]))),.SDcols=nonnumeric_column]

但出现错误时无法正常工作。

在我想要的输出中;在子集表中,region列应当是因子并且具有从bigger_table导出的级别region_1region_2region_3region_4

提前谢谢。

您可以执行以下操作:

subset_table[, 
(nonnumeric_column) := 
lapply(nonnumeric_column, (x) factor(get(x), levels = unique(bigger_table[[x]])))
]

导致

> lapply(subset_table, levels)
$region
[1] "region_1" "region_3" "region_2" "region_4"
$factor_column
[1] "C" "B" "A"
$numeric_column
NULL

原始解决方案中的问题是x返回的不是列的名称,而是实际的列。你可以用看到这一点

subset_table[, lapply(.SD, (x) print(x)), .SDcols=nonnumeric_column]

考虑到级别不会提供简单的解决方案吗?

subset_table$region <- factor(subset_table$region, levels = unique(bigger_table$region))

如果问题是在多个列上执行,那么dplyr解决方案将是:

library(dplyr)
subset_table <- subset_table |>
mutate(across(all_of(nonnumeric_column), ~ factor(.x, levels = unique(bigger_table$region))))

请注意,您的CCD_;factor_ column";,不映射到区域,因此更改为所有<NA>

在MWE中,最简单的解决方案是在较大的表中创建一个因子,然后在数据的每个子集中保留因子级别。

# Easiest solution: Create a factor in the original table and the subset retains the levels
library(data.table)
set.seed(1453)
bigger_table <- data.table(region = factor(paste0(rep('region_',50),sample(1:4,50,replace=T))),
factor_column = factor(sample(LETTERS[1:3],50,replace=T)),
numeric_column = rnorm(50,20,2))
subset_table <- bigger_table[region=='region_1']
subset_table$region
#>  [1] region_1 region_1 region_1 region_1 region_1 region_1 region_1 region_1
#>  [9] region_1 region_1 region_1 region_1 region_1 region_1 region_1
#> Levels: region_1 region_2 region_3 region_4

创建于2021-11-11由reprex包(v2.0.1(

如果您必须使用另一个表来更新它们,那么您可以使用以下代码。在您的案例中,出现了一个错误,因为在unique(bigger_table[,x])中,x不是列名,而是该列的内容。

# Update a table with the factor levels of another table
library(data.table)
set.seed(1453)
bigger_table <- data.table(region = paste0(rep('region_',50),sample(1:4,50,replace=T)),
factor_column = factor(sample(LETTERS[1:3],50,replace=T)),
numeric_column = rnorm(50,20,2))
subset_table <- bigger_table[region=='region_1']
nonnumeric_column <- names(bigger_table)[sapply(bigger_table,function(x) !is.numeric(x))]
for(col in nonnumeric_column) {
set(subset_table, j = col, value = factor(subset_table[, get(col)], levels = bigger_table[, unique(get(col))]))
}
subset_table$region
#>  [1] region_1 region_1 region_1 region_1 region_1 region_1 region_1 region_1
#>  [9] region_1 region_1 region_1 region_1 region_1 region_1 region_1
#> Levels: region_1 region_3 region_2 region_4

创建于2021-11-11由reprex包(v2.0.1(

最新更新