You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将R中data.table的melt与dcast转换为dplyr的pivot_longer与pivot_wider?

将data.table的melt/dcast逻辑转换为dplyr的pivot_longer/pivot_wider

示例数据

input_ds_wt = structure(list(id = c(1, 2, 3, 4, 5, 6), wt.mean_v1 = c(1, 1, 
1.3, 2.3, 1, 0), wt.mean_v2 = c(0.8, 0.2, 0.8, 0.2, 0.8, 0.2), 
    wt.SE_v1 = c(0.1, 0.01, 0.2, 0.02, 0.3, 0.03), wt.SE_v2 = c(0.03, 
    0.3, 0.01, 0.1, 0.4, 0.04), RSE_v1 = c(0.1, 0.01, 0.153846153846154, 
    0.00869565217391304, 0.3, Inf), RSE_v2 = c(0.0375, 1.5, 0.0125, 
    0.5, 0.5, 0.2)), class = "data.frame", row.names = c(NA, 
-6L))

数据预览:

id wt.mean_v1 wt.mean_v2 wt.SE_v1 wt.SE_v2      RSE_v1 RSE_v2
1  1        1.0        0.8     0.10     0.03 0.100000000 0.0375
2  2        1.0        0.2     0.01     0.30 0.010000000 1.5000
3  3        1.3        0.8     0.20     0.01 0.153846154 0.0125
4  4        2.3        0.2     0.02     0.10 0.008695652 0.5000
5  5        1.0        0.8     0.30     0.40 0.300000000 0.5000
6  6        0.0        0.2     0.03     0.04         Inf 0.2000

原data.table实现代码

library(data.table)

setDT(input_ds_wt)

#1. 重塑拆分版本信息
x <- melt(input_ds_wt, id.vars = "id")
x[, c("variable", "version") := tstrsplit(variable, split = "_") ]

#2. 按版本展开变量
x <- dcast(x, id  + version ~ variable, value.var = "value")

#3. 计算suppress列
x[, suppress := fifelse(RSE < 0.3 & wt.mean > 0.9, 0, 1) ]

#4. 重新融合并拼接变量与版本名
x <- melt(x, id.vars = c("id", "version") )
x[, variable := paste(variable, version, sep = "_") ]

#5. 恢复原始数据结构
x <- dcast(x, id ~ variable, value.var = "value")

运行结果:

Key: <id>
      id      RSE_v1 RSE_v2 suppress_v1 suppress_v2 wt.SE_v1 wt.SE_v2 wt.mean_v1 wt.mean_v2
   <num>       <num>  <num>       <num>       <num>    <num>    <num>      <num>      <num>
1:     1 0.100000000 0.0375           0           1     0.10     0.03        1.0        0.8
2:     2 0.010000000 1.5000           0           1     0.01     0.30        1.0        0.2
3:     3 0.153846154 0.0125           0           1     0.20     0.01        1.3        0.8
4:     4 0.008695652 0.5000           0           1     0.02     0.10        2.3        0.2
5:     5 0.300000000 0.5000           1           1     0.30     0.40        1.0        0.8
6:     6         Inf 0.2000           1           1     0.03     0.04        0.0        0.2

dplyr分步实现

第一步:拆分变量与版本(已完成)

library(dplyr)
library(tidyr)

input_ds_wt <- input_ds_wt %>% as_tibble()

# 1. 重塑拆分版本信息
step1 <- input_ds_wt %>% 
  pivot_longer(cols = !id,
               names_to = c("variable", "version"),
               names_pattern = "(.*)_(.*)")

step1预览:

# A tibble: 36 x 4
      id variable version  value
   <dbl> <chr>    <chr>    <dbl>
 1     1 wt.mean  v1      1     
 2     1 wt.mean  v2      0.8   
 3     1 wt.SE    v1      0.1   
 4     1 wt.SE    v2      0.03  
 5     1 RSE      v1      0.1   
 6     1 RSE      v2      0.0375
 7     2 wt.mean  v1      1     
 8     2 wt.mean  v2      0.2   
 9     2 wt.SE    v1      0.01  
10     2 wt.SE    v2      0.3  

第二步:按版本展开变量(对应dcast)

使用pivot_wider,指定分组列id和version,将variable列的值作为新列名,value列的值作为对应列的内容,即可实现dcast的效果:

# 2. 按版本展开变量
step2 <- step1 %>% 
  pivot_wider(id_cols = c(id, version),
              names_from = variable,
              values_from = value)

step2预览:

# A tibble: 12 x 5
      id version     RSE wt.SE wt.mean
   <dbl> <chr>     <dbl> <dbl>   <dbl>
 1     1 v1      0.1     0.1      1   
 2     1 v2      0.0375  0.03     0.8 
 3     2 v1      0.01    0.01     1   
 4     2 v2      1.5     0.3      0.2 
 5     3 v1      0.154   0.2      1.3 
 6     3 v2      0.0125  0.01     0.8 
 7     4 v1      0.00870 0.02     2.3 
 8     4 v2      0.5     0.1      0.2 
 9     5 v1      0.3     0.3      1   
10     5 v2      0.5     0.4      0.8 
11     6 v1      Inf     0.03     0   
12     6 v2      0.2     0.04     0.2

完整dplyr流程

将所有步骤串联,得到与data.table完全一致的结果:

final_result <- input_ds_wt %>% 
  as_tibble() %>%
  # 1. 拆分变量与版本
  pivot_longer(cols = !id,
               names_to = c("variable", "version"),
               names_pattern = "(.*)_(.*)") %>%
  # 2. 按版本展开变量
  pivot_wider(id_cols = c(id, version),
              names_from = variable,
              values_from = value) %>%
  # 3. 计算suppress列
  mutate(suppress = ifelse(RSE < 0.3 & wt.mean > 0.9, 0, 1)) %>%
  # 4. 重新融合并拼接变量名与版本
  pivot_longer(cols = !c(id, version),
               names_to = "variable") %>%
  mutate(variable = paste(variable, version, sep = "_")) %>%
  # 5. 恢复原始数据结构
  pivot_wider(id_cols = id,
              names_from = variable,
              values_from = value) %>%
  # 按id排序,匹配data.table结果顺序
  arrange(id)

最终结果预览:

# A tibble: 6 x 9
     id RSE_v1 RSE_v2 suppress_v1 suppress_v2 wt.SE_v1 wt.SE_v2 wt.mean_v1 wt.mean_v2
  <dbl>  <dbl>  <dbl>       <dbl>       <dbl>    <dbl>    <dbl>      <dbl>      <dbl>
1     1  0.1    0.0375           0           1     0.1      0.03        1          0.8
2     2  0.01   1.5              0           1     0.01     0.3         1          0.2
3     3  0.154  0.0125           0           1     0.2      0.01        1.3        0.8
4     4  0.0087 0.5              0           1     0.02     0.1         2.3        0.2
5     5  0.3    0.5              1           1     0.3      0.4         1          0.8
6     6  Inf    0.2              1           1     0.03     0.04        0          0.2

内容的提问来源于stack exchange,提问作者abrar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 15:44:52