繁体   English   中英

在 R 中收集和变异多个列

[英]Gather and mutate multiple columns in R

我有三个测量值,每个测量值都有两个时间点。

library(tidyverse)
library(tableone)

test_1_pre <- c(1,5,8,2)
test_1_post <- c(2,7,3,6)
test_2_pre <- c(6,3,6,5)
test_2_post <- c(9,8,9,1)
test_3_pre <- c(12,2,4,6)
test_3_post <- c(4,7,6,6)

df <- data.frame(test_1_pre, test_1_post, test_2_pre,
                 test_2_post, test_3_pre, test_3_post)

df_2 <- df %>%
  gather(test_1_pre, test_1_post,
         key="test_1_old", value="test_1") %>%
  gather(test_2_pre, test_2_post,
         key="test_2_old", value="test_2") %>%
  gather(test_3_pre, test_3_post,
         key="test_3_old", value="test_3") %>%
  mutate(pre_post = case_when(test_1_old == "test_1_pre" ~ 'pre',
                              test_1_old == "test_1_post" ~'post',
                              test_1_old == "test_2_pre" ~ 'pre',
                              test_1_old == "test_2_post" ~ 'post',
                              test_1_old == "test_3_pre" ~ 'pre',
                              test_1_old == "test_3_post" ~'post'))

vars_df <- c("test_1", "test_2", "test_3")


table_df <- CreateTableOne(vars = vars_df,
                                 data = df_2,
                                 strata = "pre_post")

tabelle.table_df<-print(table_df)

我的目标是获得一个表格,比较不同测试的“前”和“后”两个时间点。

它适用于测试 1,但不适用于以下测试。

谁能帮忙,将不胜感激!

Result:

                    Stratified by pre_post
                     post        pre         p      test
  n                    16          16                   
  test_1 (mean (sd)) 4.50 (2.13) 4.00 (2.83)  0.576     
  test_2 (mean (sd)) 5.88 (2.75) 5.88 (2.75)  1.000     
  test_3 (mean (sd)) 5.88 (2.85) 5.88 (2.85)  1.000 

nr <- c("1", "2", "3", "4")
test_1_pre <- c(1,5,8,2)
test_1_post <- c(2,7,3,6)
test_2_pre <- c(6,3,6,5)
test_2_post <- c(9,8,9,1)
test_3_pre <- c(12,2,4,6)
test_3_post <- c(4,7,6,6)

df <- data.frame(nr, test_1_pre, test_1_post, test_2_pre,
                 test_2_post, test_3_pre, test_3_post)

df_2 <- df %>%
  gather(test_1_pre, test_1_post, test_2_pre, test_2_post,
         test_3_pre, test_3_post,
         key="score", value="value") %>%
  mutate(pre_post = case_when(score == "test_1_pre" ~ 'pre',
                              score == "test_1_post" ~'post',
                              score == "test_2_pre" ~ 'pre',
                              score == "test_2_post" ~ 'post',
                              score == "test_3_pre" ~ 'pre',
                              score == "test_3_post" ~'post'))%>%
  pivot_wider(names_from="score", values_from="value")%>%
  gather(test_1_pre, test_1_post,
         key="test_1_old", value="test_1") %>%
  gather(test_2_pre, test_2_post,
         key="test_2_old", value="test_2") %>%
  gather(test_3_pre, test_3_post,
         key="test_3_old", value="test_3")

vars_df <- c("test_1", "test_2", "test_3")


table_df <- CreateTableOne(vars = vars_df,
                                 data = df_2,
                                 strata = "pre_post")

tabelle.table_df<-print(table_df)

找到解决方案:首先将所有内容收集到一个列中,改变新列,再次展开列并分别收集它们。

                   Stratified by pre_post
                     post        pre         p      test
  n                    32          32                   
  test_1 (mean (SD)) 4.50 (2.13) 4.00 (2.83)  0.576     
  test_2 (mean (SD)) 6.75 (3.45) 5.00 (1.26)  0.067     
  test_3 (mean (SD)) 5.75 (1.13) 6.00 (3.86)  0.805   


出现问题是因为您创建的pre_post列对于测试 2 和 3 不正确,您可以通过检查df_2 dataframe 来验证。 例如 output 中的第 5 行是:

test_1_post      2  test_2_pre      6  test_3_pre     12     post

虽然在许多情况下单个数据管道是合适的,但通过拆分表并使用union_all更容易解决此问题,如下所示:

library(tidyverse)
library(tableone)

test_1_pre <- c(1,5,8,2)
test_1_post <- c(2,7,3,6)
test_2_pre <- c(6,3,6,5)
test_2_post <- c(9,8,9,1)
test_3_pre <- c(12,2,4,6)
test_3_post <- c(4,7,6,6)

df <- data.frame(test_1_pre, test_1_post, test_2_pre,
                 test_2_post, test_3_pre, test_3_post)

get_dfs <- function(df, suffix) {
  df %>% 
    select(ends_with(suffix)) %>% 
    mutate(pre_post = suffix) %>% 
    # Drop _pre / _post suffixes in test column names ahead of union
    rename_with(.fn = function(x) gsub(paste0("_", suffix), "", x),
                .cols = starts_with("test"))
}

df_2 <- union_all(get_dfs(df, "pre"), get_dfs(df, "post"))

vars_df <- c("test_1", "test_2", "test_3")

table_df <- CreateTableOne(vars = vars_df,
                           data = df_2,
                           strata = "pre_post")

table_df

给出的 output 是:

# Stratified by pre_post
# post        pre         p      test
# n                     4           4                   
# test_1 (mean (SD)) 4.50 (2.38) 4.00 (3.16)  0.809     
# test_2 (mean (SD)) 6.75 (3.86) 5.00 (1.41)  0.427     
# test_3 (mean (SD)) 5.75 (1.26) 6.00 (4.32)  0.915     

与@Frank 的答案相比,这包含由不同估计标准误差产生的更保守的 p 值。

此外, df_2的结构更简洁:

# test_1 test_2 test_3 pre_post
#      1      6     12      pre
#      5      3      2      pre
#      8      6      4      pre
#      2      5      6      pre
#      2      9      4     post
#      7      8      7     post
#      3      9      6     post
#      6      1      6     post

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM