2

假设我有一个数据集 df,其中我想X在多个列的值之间匹配 col 的值,A to F并希望在新列中返回匹配的列名(否则 NA)。

输入

df <- structure(list(A = c(4L, NA, NA, NA), B = c(NA, 5L, NA, NA), 
    C = c(NA, NA, NA, NA), D = c(NA, 4L, 6L, 7L), E = c(5L, NA, 
    NA, NA), F = c(NA, NA, NA, NA), X = 4:7), class = "data.frame", row.names = c(NA, 
-4L))

> df
   A  B  C  D  E  F X
1  4 NA NA NA  5 NA 4
2 NA  5 NA  4 NA NA 5
3 NA NA NA  6 NA NA 6
4 NA NA NA  7 NA NA 7

我想要的输出

> df_out
   A  B  C  D  E  F X new
1  4 NA NA NA  5 NA 4   A
2 NA  5 NA  4 NA NA 5   B
3 NA NA NA  6 NA NA 6   D
4 NA NA NA  7 NA NA 7   D

我会更喜欢dplyr/tidyverse语法,我将集成到我现有的语法中。

4

3 回答 3

3

一种选择可能是:

df %>%
 rowwise() %>%
 mutate(new = names(.)[which(c_across(-X) %in% X)])

      A     B C         D     E F         X new  
  <int> <int> <lgl> <int> <int> <lgl> <int> <chr>
1     4    NA NA       NA     5 NA        4 A    
2    NA     5 NA        4    NA NA        5 B    
3    NA    NA NA        6    NA NA        6 D    
4    NA    NA NA        7    NA NA        7 D

上面的解决方案假定列名对应于which(). 但是,如果不是这种情况(例如c_across(-c(C, E, X)),则结果将不正确。更复杂情况的解决方案可能是:

df %>%
 mutate(new = Reduce(coalesce, across(-c(C, E, X), ~ ifelse(. == X, cur_column(), NA_character_))))
                          
   A  B  C  D  E  F X new
1  4 NA NA NA  5 NA 4   A
2 NA  5 NA  4 NA NA 5   B
3 NA NA NA  6 NA NA 6   D
4 NA NA NA  7 NA NA 7   D
于 2021-01-30T10:09:53.350 回答
2
df %>%
  pivot_longer(cols = -X) %>%
  mutate(
    match = if_else(X == value, name, NA_character_)
  ) %>%
  pivot_wider() %>%
  filter(!is.na(match))
于 2021-01-30T10:41:36.230 回答
2

A:F列与X列进行比较,将NA's替换为FALSE并用于max.col获取TRUE每行中的值索引,该索引可用于获取列名。

library(dplyr)

df %>%
  mutate(new = {
    tmp <- select(., A:F) == X
    names(.)[max.col(replace(tmp, is.na(tmp), FALSE))]
  })

#   A  B  C  D  E  F X new
#1  4 NA NA NA  5 NA 4   A
#2 NA  5 NA  4 NA NA 5   B
#3 NA NA NA  6 NA NA 6   D
#4 NA NA NA  7 NA NA 7   D

在基数 R 中,这可以写成:

tmp <- df[1:5] == df$X
df$new <- names(df)[max.col(replace(tmp, is.na(tmp), FALSE))]

此解决方案假定您在行中至少有一个匹配项X,如示例中所示。

于 2021-01-30T11:27:03.750 回答