【问题标题】:Gather twice in same data frame在同一数据框中收集两次
【发布时间】:2018-11-26 22:14:29
【问题描述】:

我有一个数据框,我想在其中进行两次单独的收集

library(tidyverse)
id <- c("A","B","C","D","E")
test_1_baseline <- c(1,2,4,5,6)
test_2_baseline <- c(21000, 23400, 26800,29000,30000)
test_1_followup <- c(0,4,2,3,1)
test_2_followup <- c(10000,12000,13000,15000,21000)
layout_1 <-data.frame(id,test_1_baseline,test_1_followup,test_2_baseline,test_2_followup)

这是当前布局。 每人1行。 基线测试 1 的结果是一个变量 基线测试 2 的结果是第二个变量 Test 1/2 的随访结果也是如此

我希望数据更整洁。一列时间点,一列测试A结果,一列测试B结果。

id2 <- c("A","B","C","D","E","A","B","C","D","E")
time <- c(rep("baseline",5),rep("followup",5))
test_1_result <- c(1,2,4,5,6,0,4,2,3,1)
test_2_result <- c(21000, 23400, 26800,29000,30000,10000,12000,13000,15000,21000)
layout_2 <- data.frame(id2, time,test_1_result,test_2_result)

我目前正在做一个在我看来很奇怪的过程,首先我收集测试 1 数据

test_1 <-  select(layout_1,id,test_1_baseline,test_1_followup) %>%
  gather("Timepoint","test_1",c(test_1_baseline,test_1_followup)) %>% 
  mutate(Timepoint = replace(Timepoint,Timepoint=="test_1_baseline", "baseline")) %>%
  mutate(Timepoint = replace(Timepoint,Timepoint=="test_1_followup", "followup"))

然后我对测试 2 做同样的事情并加入他们

test_2 <- select(layout_1,id,test_2_baseline,test_2_followup) %>%
  gather("Timepoint","test_2",c(test_2_baseline,test_2_followup)) %>% 
  mutate(Timepoint = replace(Timepoint,Timepoint=="test_2_baseline", "baseline")) %>%
  mutate(Timepoint = replace(Timepoint,Timepoint=="test_2_followup", "followup"))   

test_combined <- full_join(test_1,test_2)

我尝试在同一个数据帧上进行第一次 Gather 和第二次 Gather,但最终会出现重复;即你最终得到了

  1. ID 1 测试_1 基线测试_2 基线
  2. ID 1 测试_1 基线测试_2 跟进
  3. ID 1 测试_1 后续测试_2
  4. 基线 ID 1 测试_1 跟进测试_2 跟进 == 4 行,应该只有 2 行

我觉得必须有一种更清洁的 tidyverse 方式来做到这一点。 欢迎指导

【问题讨论】:

    标签: r tidyverse tidyr


    【解决方案1】:

    data.table 的一个选项使用 melt 可以采用多个 measure patterns

    library(data.table)
    nm1 <- unique(sub(".*_", "", names(layout_1)[-1]))
    melt(setDT(layout_1), measure = patterns("test_1", "test_2"),
              value.name = c('test_1_result', 'test_2_result'), 
              variable.name = 'time')[, time := nm1[time]][]
    

    【讨论】:

      【解决方案2】:

      您可以gatherid 之外的所有列,然后使用separate 拆分为结果和时间。

      请注意,此代码假定结果名称始终为 6 个字符(test_1test_2),并根据该假设进行分隔。如果不是这种情况,您将需要设计一个不同的separate

      library(tidyr)
      library(dplyr)
      
      layout_1 %>% 
        gather(Var, Val, -id) %>% 
        separate(Var, into = c("result", "time"), sep = 6) %>% 
        spread(result, Val) %>% 
        mutate(time = gsub("_", "", time))
      

      结果:

         id     time test_1 test_2
      1   A baseline      1  21000
      2   A followup      0  10000
      3   B baseline      2  23400
      4   B followup      4  12000
      5   C baseline      4  26800
      6   C followup      2  13000
      7   D baseline      5  29000
      8   D followup      3  15000
      9   E baseline      6  30000
      10  E followup      1  21000
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-27
        • 2022-07-31
        • 1970-01-01
        • 2018-04-26
        相关资源
        最近更新 更多