如何将 R 中带有类别值的 df 与另一个具有相应值的 df 合并?

  • 本文关键字:df 另一个 合并 r merge label levels
  • 更新时间 :
  • 英文 :


编辑: 改写: 所描述的情况可能是从不同统计程序中提取数据的结果,这些程序可以单独生成具有(a)因子水平和(b)其相应的分配"数字"值的csv文件。

1)我可能有很多因子变量,例如性别,年龄范围,这些因子变量具有水平,例如男性/名人,18-30/31-40等。 2)这些级别分配给某些数字,无论是否有序。 3) 因子/水平数据帧是一个数据帧/数据集。分配给因子水平数据集是一个单独的数据帧。 4)我想将这两个数据集合并为一个数据集。 这意味着必须保留有序因子水平并将其正确分配给其相应的数字。

因此,因子水平及其分配的数字被保存在两个不同的数据集(例如.csv文件中)。这两个数据帧必须"合并"。

我该怎么做? 附言这两个数据集之间有一个 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"))

这个问题并不完全清楚:

  • 术语merge用于我们谈论根据某个键组合的两个数据帧。
  • 术语levelslabelsfactors一起使用

我们将尝试这两种变体,并希望 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.frame 的数据汇集在一起。如果两个 data.frame 中的匹配列被平等命名,例如d1,那会容易得多。因此,我们必须将DF1d1_levelsDF2d1_labels结合在一起。

获取列的基本名称

base_names <- na.omit(unique(stringr::str_extract(c(names(DF1), names(DF2)), ".+(?=_levels$)")))
base_names
#[1] "d1" "d2" "d3"

创建新的数据帧

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"

最新更新