如何将 R 中具有类别值的 df 与另一个具有相应值的 df 合并?
How can I merge a df in R with category values with another df with its corresponding values?
编辑:改写:
所描述的情况可能是从不同的统计程序中提取数据的结果,这些程序可能会生成单独的 csv 文件,其中包含 (a) 因子水平和 (b) 相应分配的 "numerical" 值。
1) 我可能有很多因子变量,例如性别、年龄范围和这些因素变量具有水平,例如male/famele、18-30/31-40 等
2)这些级别被分配给一些数字,无论是有序的还是无序的。
3) factor/level 数据框是一个数据框/数据集。分配给因子水平的数据集是一个单独的数据框。
4) 我想将这两个数据集合并为一个。
这意味着必须保留有序的因子水平并将其正确分配给相应的数字。
因此,因子水平及其分配的数字保存在两个不同的数据集(例如 csv 文件)中。这两个数据帧必须是"merged"。
我该怎么做?
p.s。这两个数据集之间有一个 cmmon ID 变量。
d1_levels d2_levels d3_levels
1 2 2 0
2 0 1 2
3 1 2 1
4 2 2 2
d1_labels d2_labels d3_labels
1 boy east <3kg
2 dont know south 3kg
3 girl east >3kg
4 boy east 3kg
我希望 d1_labels 与以下 R 命令
的结果相同
dataset$d1_labels<- factor(d1_levels, levels = c(0,1,2), labels = c("dont know", "girl", "boy"))
问题不完全清楚:
- 当我们谈论两个 data.frames 根据某个键组合时,使用术语
merge
。
- 术语
levels
和 labels
与 factors
一起使用
我们将尝试这两种变体,希望 OP 能具体说明他想要什么。
合并
merge(DF1, DF2, by = "rn")
# rn d1_levels d2_levels d3_levels d1_labels d2_labels d3_labels
#1 1 2 2 0 boy east <3kg
#2 2 0 1 2 dont know south 3kg
#3 3 1 2 1 girl east >3kg
#4 4 2 2 2 boy east 3kg
因素
reorder(factor(DF2$d1_labels), DF1$d1_levels)
#[1] boy dont know girl boy
#attr(,"scores")
# boy dont know girl
# 2 0 1
#Levels: dont know girl boy
reorder(factor(DF2$d2_labels), DF1$d2_levels)
#[1] east south east east
#attr(,"scores")
# east south
# 2 1
#Levels: south east
reorder(factor(DF2$d3_labels), DF1$d3_levels)
#[1] <3kg 3kg >3kg 3kg
#attr(,"scores")
#<3kg >3kg 3kg
# 0 1 2
#Levels: <3kg >3kg 3kg
factor()
创建因子,reorder()
根据级别列中给出的顺序对因子级别排序。在 R 中,级别编号从 1 开始。
单个结果可以组合回一个数据框(但请注意,这不是 R 中手动转换多列的首选方式。)
result <- data.frame(
rn = DT1$rn,
d1 = reorder(factor(DF2$d1_labels), DF1$d1_levels),
d2 = reorder(factor(DF2$d2_labels), DF1$d2_levels),
d3 = reorder(factor(DF2$d3_labels), DF1$d3_levels)
)
组合多个因子列的水平和标签
OP 已经澄清了这个问题,并且 将水平和标签组合起来多达 500 个因子列。
不幸的是,这非常复杂,因为它需要将来自两个不同 data.frames 且命名不同的数据汇集在一起。如果 data.frames 中的匹配列的名称相同,例如 d1
,那就容易多了。因此,我们必须将 DF1
中的 d1_levels
与 DF2
中的 d1_labels
组合在一起。
获取列的基本名称
base_names <- na.omit(unique(stringr::str_extract(c(names(DF1), names(DF2)), ".+(?=_levels$)")))
base_names
#[1] "d1" "d2" "d3"
新建data.frame
result <- as.data.frame(
setNames(
lapply(base_names, function(x) {
reorder(factor(DF2[[paste0(x, "_labels")]]), DF1[[paste0(x, "_levels")]])
}), base_names
)
)
result
# d1 d2 d3
#1 boy east <3kg
#2 dont know south 3kg
#3 girl east >3kg
#4 boy east 3kg
str(result)
#'data.frame': 4 obs. of 3 variables:
# $ d1: Factor w/ 3 levels "dont know","girl",..: 3 1 2 3
# ..- attr(*, "scores")= num [1:3(1d)] 2 0 1
# .. ..- attr(*, "dimnames")=List of 1
# .. .. ..$ : chr "boy" "dont know" "girl"
# $ d2: Factor w/ 2 levels "south","east": 2 1 2 2
# ..- attr(*, "scores")= num [1:2(1d)] 2 1
# .. ..- attr(*, "dimnames")=List of 1
# .. .. ..$ : chr "east" "south"
# $ d3: Factor w/ 3 levels "<3kg",">3kg",..: 1 3 2 3
# ..- attr(*, "scores")= num [1:3(1d)] 0 1 2
# .. ..- attr(*, "dimnames")=List of 1
# .. .. ..$ : chr "<3kg" ">3kg" "3kg"
编辑:改写: 所描述的情况可能是从不同的统计程序中提取数据的结果,这些程序可能会生成单独的 csv 文件,其中包含 (a) 因子水平和 (b) 相应分配的 "numerical" 值。
1) 我可能有很多因子变量,例如性别、年龄范围和这些因素变量具有水平,例如male/famele、18-30/31-40 等 2)这些级别被分配给一些数字,无论是有序的还是无序的。 3) factor/level 数据框是一个数据框/数据集。分配给因子水平的数据集是一个单独的数据框。 4) 我想将这两个数据集合并为一个。 这意味着必须保留有序的因子水平并将其正确分配给相应的数字。
因此,因子水平及其分配的数字保存在两个不同的数据集(例如 csv 文件)中。这两个数据帧必须是"merged"。
我该怎么做? p.s。这两个数据集之间有一个 cmmon ID 变量。
d1_levels d2_levels d3_levels
1 2 2 0
2 0 1 2
3 1 2 1
4 2 2 2
d1_labels d2_labels d3_labels
1 boy east <3kg
2 dont know south 3kg
3 girl east >3kg
4 boy east 3kg
我希望 d1_labels 与以下 R 命令
的结果相同dataset$d1_labels<- factor(d1_levels, levels = c(0,1,2), labels = c("dont know", "girl", "boy"))
问题不完全清楚:
- 当我们谈论两个 data.frames 根据某个键组合时,使用术语
merge
。 - 术语
levels
和labels
与factors
一起使用
我们将尝试这两种变体,希望 OP 能具体说明他想要什么。
合并
merge(DF1, DF2, by = "rn")
# rn d1_levels d2_levels d3_levels d1_labels d2_labels d3_labels
#1 1 2 2 0 boy east <3kg
#2 2 0 1 2 dont know south 3kg
#3 3 1 2 1 girl east >3kg
#4 4 2 2 2 boy east 3kg
因素
reorder(factor(DF2$d1_labels), DF1$d1_levels)
#[1] boy dont know girl boy
#attr(,"scores")
# boy dont know girl
# 2 0 1
#Levels: dont know girl boy
reorder(factor(DF2$d2_labels), DF1$d2_levels)
#[1] east south east east
#attr(,"scores")
# east south
# 2 1
#Levels: south east
reorder(factor(DF2$d3_labels), DF1$d3_levels)
#[1] <3kg 3kg >3kg 3kg
#attr(,"scores")
#<3kg >3kg 3kg
# 0 1 2
#Levels: <3kg >3kg 3kg
factor()
创建因子,reorder()
根据级别列中给出的顺序对因子级别排序。在 R 中,级别编号从 1 开始。
单个结果可以组合回一个数据框(但请注意,这不是 R 中手动转换多列的首选方式。)
result <- data.frame(
rn = DT1$rn,
d1 = reorder(factor(DF2$d1_labels), DF1$d1_levels),
d2 = reorder(factor(DF2$d2_labels), DF1$d2_levels),
d3 = reorder(factor(DF2$d3_labels), DF1$d3_levels)
)
组合多个因子列的水平和标签
OP 已经澄清了这个问题,并且
不幸的是,这非常复杂,因为它需要将来自两个不同 data.frames 且命名不同的数据汇集在一起。如果 data.frames 中的匹配列的名称相同,例如 d1
,那就容易多了。因此,我们必须将 DF1
中的 d1_levels
与 DF2
中的 d1_labels
组合在一起。
获取列的基本名称
base_names <- na.omit(unique(stringr::str_extract(c(names(DF1), names(DF2)), ".+(?=_levels$)")))
base_names
#[1] "d1" "d2" "d3"
新建data.frame
result <- as.data.frame(
setNames(
lapply(base_names, function(x) {
reorder(factor(DF2[[paste0(x, "_labels")]]), DF1[[paste0(x, "_levels")]])
}), base_names
)
)
result
# d1 d2 d3
#1 boy east <3kg
#2 dont know south 3kg
#3 girl east >3kg
#4 boy east 3kg
str(result)
#'data.frame': 4 obs. of 3 variables:
# $ d1: Factor w/ 3 levels "dont know","girl",..: 3 1 2 3
# ..- attr(*, "scores")= num [1:3(1d)] 2 0 1
# .. ..- attr(*, "dimnames")=List of 1
# .. .. ..$ : chr "boy" "dont know" "girl"
# $ d2: Factor w/ 2 levels "south","east": 2 1 2 2
# ..- attr(*, "scores")= num [1:2(1d)] 2 1
# .. ..- attr(*, "dimnames")=List of 1
# .. .. ..$ : chr "east" "south"
# $ d3: Factor w/ 3 levels "<3kg",">3kg",..: 1 3 2 3
# ..- attr(*, "scores")= num [1:3(1d)] 0 1 2
# .. ..- attr(*, "dimnames")=List of 1
# .. .. ..$ : chr "<3kg" ">3kg" "3kg"