Я работаю с большим набором данных. В этом наборе данных есть столбец со ссылочным кодом и другие столбцы со значениями ИСТИНА или ЛОЖЬ. Я пытаюсь создать новый столбец, который собирает конкатенированные (или в виде списка) имена столбцов, значение которых равно TRUE. Упрощение фрейма данных будет выглядеть примерно так:
data <- data.frame( Reference = c("001", "002", "003", "004", "005"),
Column A = c(TRUE, TRUE, FALSE, TRUE, FALSE),
Column B = c(FALSE, TRUE, TRUE, FALSE, FALSE),
Column C = c(TRUE, FALSE, TRUE, FALSE, TRUE))
data
Ожидаемый результат будет примерно таким:
Я знаю, как создавать поля, объединяя значения или имена столбцов, но я не знаю, как ввести условное выражение, чтобы оно принимало только имена столбцов, значение которых равно TRUE.
Огромное спасибо заранее!!
Базовое решение R
data <- data.frame( Reference = c("001", "002", "003", "004", "005"),
Column_A = c(TRUE, TRUE, FALSE, TRUE, FALSE),
Column_B = c(FALSE, TRUE, TRUE, FALSE, FALSE),
Column_C = c(TRUE, FALSE, TRUE, FALSE, TRUE))
L <- apply(data, 1, function(i) which(i == TRUE))
data$Column_D <- lapply(L, function(x) paste0(names(x), collapse = ", "))
# Reference Column_A Column_B Column_C Column_D
# 1 001 TRUE FALSE TRUE Column_A, Column_C
# 2 002 TRUE TRUE FALSE Column_A, Column_B
# 3 003 FALSE TRUE TRUE Column_B, Column_C
# 4 004 TRUE FALSE FALSE Column_A
# 5 005 FALSE FALSE TRUE Column_C
tidyverse
решение с tidyr::unite()
:
library(tidyverse)
data %>%
mutate(unite(across(starts_with('Column'), ~ ifelse(.x, cur_column(), NA)),
col = 'Column_D', sep = ', ', na.rm = TRUE))
# Reference Column_A Column_B Column_C Column_D
# 1 001 TRUE FALSE TRUE Column_A, Column_C
# 2 002 TRUE TRUE FALSE Column_A, Column_B
# 3 003 FALSE TRUE TRUE Column_B, Column_C
# 4 004 TRUE FALSE FALSE Column_A
# 5 005 FALSE FALSE TRUE Column_C
Еще dplyr
вариант:
data %>%
rowwise() %>%
mutate(Column_D = toString(names(across(starts_with("Column")))[which(c_across(starts_with("Column")))]))
Reference Column_A Column_B Column_C Column_D
<chr> <lgl> <lgl> <lgl> <chr>
1 001 TRUE FALSE TRUE Column_A, Column_C
2 002 TRUE TRUE FALSE Column_A, Column_B
3 003 FALSE TRUE TRUE Column_B, Column_C
4 004 TRUE FALSE FALSE Column_A
5 005 FALSE FALSE TRUE Column_C
Или просто
apply(data[-1], 1, \(i)toString(names(which(i))))