R:通过正则表达式匹配迭代数据帧中的列对

时间:2018-04-15 03:21:51

标签: r dplyr

我需要迭代数据帧中的一对列。每列都有一个带有“_ans”后缀(和相同前缀)的相应列。如果“_ans”列和比较列相等,我需要创建带有后缀“_score”的新列。

可重复的例子:

    set.seed(42)
    df <- as.data.frame(matrix(sample(1:9, 10 * 5, replace = TRUE),
    ncol = 10, dimnames = list(NULL, c("CB1", "LB2", "CW3", "WC1",
    "LW20", "CB1_ans", "LB2_ans", "CW3_ans", "WC1_ans", "LW20_ans"))))

> df
  CB1 LB2 CW3 WC1 LW20 CB1_ans LB2_ans CW3_ans WC1_ans LW20_ans
1   3   9   6   9    1       7       3       2       5        1
2   3   3   4   2    5       1       3       7       4        4
3   7   7   7   1    7       6       4       6       3        4
4   5   8   7   5    2       6       2       7       2        3
5   6   3   3   2    3       1       9       9       1        4

如果我手动执行此操作,它将如下所示:

df$CB1_score <- df$CB1 == df$CB1_ans
df$LB2_score <- df$LB2 == df$LB2_ans
df$CB3_score <- df$CW3 == df$CW3_ans

结果输出:

  CB1 LB2 CW3 WC1 LW20 CB1_ans LB2_ans CW3_ans WC1_ans LW20_ans CB1_score LB2_score CB3_score
1   3   9   6   9    1       7       3       2       5        1     FALSE     FALSE     FALSE
2   3   3   4   2    5       1       3       7       4        4     FALSE      TRUE     FALSE
3   7   7   7   1    7       6       4       6       3        4     FALSE     FALSE     FALSE
4   5   8   7   5    2       6       2       7       2        3     FALSE     FALSE      TRUE
5   6   3   3   2    3       1       9       9       1        4     FALSE     FALSE     FALSE

等等。我已经研究了一个小时试图找到一种方法来自动化这个没有for循环,但不能想到正确的方法。

3 个答案:

答案 0 :(得分:2)

以下是使用tidyverse的{​​{1}}解决方案:

purrr:map

答案 1 :(得分:1)

一个基础R解决方案:

nms <- colnames(df)
ans <- nms[grepl("_ans$", nms)]
qstn <- gsub("_ans$", "", ans)
# in case there's something wrong with the names??
ans <- ans[ qstn %in% nms ]
qstn <- qstn[ qstn %in% nms ]


scores <- df[qstn] == df[ans]
colnames(scores) <- paste0(qstn, "_score")
cbind(df, scores)
#   CB1 LB2 CW3 WC1 LW20 CB1_ans LB2_ans CW3_ans WC1_ans LW20_ans CB1_score LB2_score CW3_score
# 1   9   5   5   9    9       5       7       8       4        9     FALSE     FALSE     FALSE
# 2   9   7   7   9    2       4       8       1       4        8     FALSE     FALSE     FALSE
# 3   3   2   9   2    9       9       4       2       1        6     FALSE     FALSE     FALSE
# 4   8   6   3   5    9       5       7       9       9        9     FALSE     FALSE     FALSE
# 5   6   7   5   6    1       8       1       6       4        6     FALSE     FALSE     FALSE
#   WC1_score LW20_score
# 1     FALSE       TRUE
# 2     FALSE      FALSE
# 3     FALSE      FALSE
# 4     FALSE       TRUE
# 5     FALSE      FALSE

答案 2 :(得分:1)

一个基本的R选项是迭代数据框中的所有列,_ans中结束,然后将它们与_ans进行比较同行。我们可以在此处使用greplsapply

cols <- names(df)[grepl("^(?!.*_ans).*$", names(df), perl=TRUE)]
for (name in cols) {
    df[paste0(name, "_score")] <- df[[name]] == df[[paste0(name, "_ans")]]
}

df

  CB1_score LB2_score CW3_score WC1_score LW20_score
1 FALSE    FALSE     FALSE     FALSE       TRUE
2 FALSE    FALSE     FALSE     FALSE      FALSE
3 FALSE    FALSE     FALSE     FALSE      FALSE
4 FALSE    FALSE     FALSE     FALSE       TRUE
5 FALSE    FALSE     FALSE     FALSE      FALSE

Demo