【问题标题】:Merging Data into a long data frame将数据合并成一个长数据框
【发布时间】:2020-09-18 21:40:44
【问题描述】:

我正在整合数据以将其放入新的数据库中,但在用新的外键 (FK) 变量替换旧列时遇到了一些问题。我将所有数据合并为长格式,然后再次转换以创建新数据模型的新表结构。由于通用变量(如“total”)的某些名称重复以及将一些旧名称合并到新名称中,直接合并并不总是有效,因为名称不匹配。我可以使用一些变通方法,也许还有一些其他概念上的改进来解决我的问题。但是,如果有一种方法可以将 FK 合并并替换为长数据表,我通常会很好奇,就像它适用于宽表一样。

用“合并”或“长”搜索线程总是会产生其他融化问题,这就是我问自己的原因。

我尝试使用“mtcars”创建一个通用示例

library(data.table)
dt<-data.table(mtcars)
#Create Id to melt the data 
dt[,id:=1:.N]
dt_long<-melt(dt, id.vars="id")
#Create a unique sub table for 4 variables of mtcars with a new sub_id
merge_cols<-c("vs","am","gear","carb")
dt_sub<-dt[,..merge_cols]
dt_sub<-unique(dt_sub)
dt_sub[,id_sub:=1:.N]
# Easy to merge with orginal table and delete old columns
dt<-merge(dt,dt_sub, by=merge_cols )
set(dt, , merge_cols, NULL)
#Any way to do this with the long data frame? 
setorder(dt_long, id)
dt_long[variable %in% merge_cols,]
dt_sub[vs==0 & am==1 & gear ==4 & carb==4,]

例如,前 4 行应替换为具有变量“sub_id”和值“4”的行。就像我要使用宽原始 dt 从上面融化合并的“dt”一样。所以我的最终结果应该看起来像我在与子表合并后融化了宽表,但是对于“merge_cols”的每四行,我们有一行带有“sub_id”

dt_final<-melt(dt,  id.vars="id"  )
dt_final[variable=="id_sub"]

【问题讨论】:

  • 我不明白您所说的“例如前 4 行应替换为具有变量 sub_id 和值 4 的一行”是什么意思。请问,你能edit你的问题并显示预期的结果吗?谢谢。
  • @Uwe 希望有帮助?我只是明确地写了 'id==1' 的条件。一般有没有办法做到这一点。我想对每个 id 都这样做,我也可以理解这是否是一个人不做的事情,因为应该使用宽表的普通合并/左连接
  • Max,感谢您的补充说明。但是,恐怕我需要看到预期的结果才能理解。谢谢。
  • @Uwe 预期结果是 'dt_final'

标签: r database merge data.table melt


【解决方案1】:

如果我理解正确(但可能我没有抓住重点),问题是如何以长格式合并或子集。也许,OP 正在寻找以下方面的内容。

第一步是了解子集化(在某种程度上)等同于与查找表合并/连接。所以,

library(data.table) # just to highlight that data.table syntax is used here
dt_sub[vs == 0 & am == 1 & gear == 4 & carb == 4, ]

返回与

相同的结果
lut_wide <- data.table(vs = 0, am = 1, gear = 4, carb = 4)
dt_sub[lut_wide, on = names(lut_wide)]
   vs am gear carb id_sub
1:  0  1    4    4      1

要在长格式中做同样的事情,还需要重新调整查找表:

lut_long <- melt(lut_wide, measure.vars = names(lut_wide))
   variable value
1:       vs     0
2:       am     1
3:     gear     4
4:     carb     4

或者,fread() 可用于从头开始创建长格式的查找表:

lut_long <- fread(
"variable, value
vs, 0
am, 1
gear, 4
carb, 4")

现在,我们需要找到满足所有 4 个条件的ids:

idx <- dt_long[lut_long, on = .(variable, value)][
  , which(.N == nrow(lut_long)), by = id][, .(id)]
idx
   id
1:  1
2:  2

或者,我们可以写

idx <- dt_long[lut_long, on = .(variable, value)][
  , .N, by = id][N == nrow(lut_long), .(id)]

最后,idx 用于子集dt_long(通过加入):

dt_long[variable %in% merge_cols, ][idx, on = "id"]
   id variable value
1:  1       vs     0
2:  1       am     1
3:  1     gear     4
4:  1     carb     4
5:  2       vs     0
6:  2       am     1
7:  2     gear     4
8:  2     carb     4

这里只考虑merge_cols 中定义的变量。

显然,结果包含重复项。这可以通过只选择idx 的第一行来删除:

dt_long[variable %in% merge_cols, ][first(idx), on = "id"]
   id variable value
1:  1       vs     0
2:  1       am     1
3:  1     gear     4
4:  1     carb     4

【讨论】:

    猜你喜欢
    • 2016-01-20
    • 2019-06-26
    • 2017-10-21
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-21
    相关资源
    最近更新 更多