data.table 更新另一个 table 的因子水平
Updating factor levels from another table by data.table
我想从另一个table更新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]
但它无法正常工作并出现错误。
在我想要的输出中;在子集 table 中,region
列应该是因子并且具有从 bigger_table
.
提前致谢。
不会考虑级别不提供简单的解决方案吗?
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))))
请注意,您的 nonnumeric_column
包括“factor_column”,它没有映射到区域,因此更改为所有 <NA>
在您的 MWE 中,最简单的解决方案是在较大的 table 中创建一个因子,然后在数据的每个子集中保留因子水平。
# 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
由 reprex package (v2.0.1)
于 2021-11-11 创建
如果您必须使用另一个 table 来更新它们,那么您可以使用以下代码。在你的例子中,有一个错误,因为在 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
由 reprex package (v2.0.1)
于 2021-11-11 创建
您可以执行以下操作:
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]
我想从另一个table更新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]
但它无法正常工作并出现错误。
在我想要的输出中;在子集 table 中,region
列应该是因子并且具有从 bigger_table
.
提前致谢。
不会考虑级别不提供简单的解决方案吗?
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))))
请注意,您的 nonnumeric_column
包括“factor_column”,它没有映射到区域,因此更改为所有 <NA>
在您的 MWE 中,最简单的解决方案是在较大的 table 中创建一个因子,然后在数据的每个子集中保留因子水平。
# 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
由 reprex package (v2.0.1)
于 2021-11-11 创建如果您必须使用另一个 table 来更新它们,那么您可以使用以下代码。在你的例子中,有一个错误,因为在 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
由 reprex package (v2.0.1)
于 2021-11-11 创建您可以执行以下操作:
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]