在 R 中合并多个变量

ran*_*ber 3 r dataframe

我有一个数据集,每个主题的不同列中包含相同的变量。我想将它们合并到同一列。

例如:,我有这个数据框,并且有三个 DV,但它们位于不同主题的不同列(A、B、C)中。

data.frame(ID = c(1,2,3), DV1_A=c(1,NA,NA), DV1_B= c(NA,4,NA), DV1_C = c(NA,NA,5), DV2_A=c(3,NA,NA), DV2_B=c(NA,3,NA), DV2_C=c(NA,NA,5), FACT = c("A","B","C"))
Run Code Online (Sandbox Code Playgroud)

如何将它们合并为两列?所以结果是:

data.frame(ID = c(1,2,3), DV1_A=c(1,NA,NA), DV1_B= c(NA,4,NA), DV1_C = c(NA,NA,5), DV2_A=c(3,NA,NA), DV2_B=c(NA,3,NA), DV2_C=c(NA,NA,5), FACT = c("A","B","C"), DV_1 = c(1,4,5), DV_2 = c(3,3,5))
Run Code Online (Sandbox Code Playgroud)

avi*_*seR 6

您可以coalesce使用dplyr

library(dplyr)

df %>%
  mutate(DV_1 = coalesce(DV1_A, DV1_B, DV1_C),
         DV_2 = coalesce(DV2_A, DV2_B, DV2_C))
Run Code Online (Sandbox Code Playgroud)

如果您有很多DV 要组合,您可能不想键入所有列名称。在这种情况下,您可以首先grep为每个 的列名称DV,将每个名称解析为带有 的符号rlang::syms,然后将!!!符号拼接()coalesce(来自@hadley的建议):

library(rlang)
var_quo1 = syms(grep("DV1", names(df), value = TRUE))
var_quo2 = syms(grep("DV2", names(df), value = TRUE))

df %>%
  mutate(DV_1 = coalesce(!!! var_quo1),
         DV_2 = coalesce(!!! var_quo2))
Run Code Online (Sandbox Code Playgroud)

相反,如果您有大量DV's,您甚至可能不想键入所有行coalesce,在这种情况下,您可以创建一个函数,DV在给定输入数字的情况下输出一列,lapply并将bind_col所有这些行组合在一起:

DV_combine = function(num_DVs){

  DV_name = sym(paste0("DV", num_DVs))
  DV_syms = syms(grep(paste0("DV", num_DVs), names(df), value = TRUE))

  df %>%
    transmute(!!DV_name := coalesce(!!! DV_syms))
}

bind_cols(df, lapply(1:2, DV_combine))
Run Code Online (Sandbox Code Playgroud)

结果:

  ID DV1_A DV1_B DV1_C DV2_A DV2_B DV2_C FACT DV_1 DV_2
1  1     1    NA    NA     3    NA    NA    A    1    3
2  2    NA     4    NA    NA     3    NA    B    4    3
3  3    NA    NA     5    NA    NA     5    C    5    5
Run Code Online (Sandbox Code Playgroud)

笔记:

此方法适用于numericcharacter类列,但不适用于factor's。在使用此方法之前,应首先将factor列转换为字符。

数据:

df = structure(list(ID = c(1, 2, 3), DV1_A = c(1, NA, NA), DV1_B = c(NA, 
4, NA), DV1_C = c(NA, NA, 5), DV2_A = c(3, NA, NA), DV2_B = c(NA, 
3, NA), DV2_C = c(NA, NA, 5), FACT = structure(1:3, .Label = c("A", 
"B", "C"), class = "factor")), .Names = c("ID", "DV1_A", "DV1_B", 
"DV1_C", "DV2_A", "DV2_B", "DV2_C", "FACT"), row.names = c(NA, 
-3L), class = "data.frame")
Run Code Online (Sandbox Code Playgroud)