如何根据其他列的真/假值创建新列?

3

我有多个包含TRUEFALSE语句的列,我想创建一个新列,其中包含真实列的列名,它应该看起来像这个例子。

颜色需要是新列。

           color   red yellow orange  blue
1           blue FALSE  FALSE  FALSE  TRUE
2      red, blue  TRUE  FALSE  FALSE  TRUE
3    blue, green FALSE  FALSE  FALSE  TRUE
4         purple FALSE  FALSE  FALSE FALSE
5 yellow, orange FALSE   TRUE   TRUE FALSE

我尝试使用case_when函数,但是有太多的排列组合需要使用。

4个回答

2
你可以在 apply 和 cbind 中对 names 进行子集操作。
cbind(dat, clr=apply(dat[-1], 1, \(x) if (any(x)) toString(names(dat)[-1][x]) else NA))
#            color   red yellow orange  blue            clr
# 1           blue FALSE  FALSE  FALSE  TRUE           blue
# 2      red, blue  TRUE  FALSE  FALSE  TRUE      red, blue
# 3    blue, green FALSE  FALSE  FALSE  TRUE           blue
# 4         purple FALSE  FALSE  FALSE FALSE           <NA>
# 5 yellow, orange FALSE   TRUE   TRUE FALSE yellow, orange

数据:

dat <- structure(list(color = c("blue", "red, blue", "blue, green", 
"purple", "yellow, orange"), red = c(FALSE, TRUE, FALSE, FALSE, 
FALSE), yellow = c(FALSE, FALSE, FALSE, FALSE, TRUE), orange = c(FALSE, 
FALSE, FALSE, FALSE, TRUE), blue = c(TRUE, TRUE, TRUE, FALSE, 
FALSE)), class = "data.frame", row.names = c(NA, -5L))

0

我会使用tidyverse,在之前以一种分离的方式创建列(可能有几种方法可以做到这一点):

# Prepare the data to add the id column
df <- df %>% 
  mutate(id = row_number())

# Compute the new column with the colors
df_new_col <- df %>% 
  pivot_longer(!id, names_to = "color", values_to = "presence") %>% 
  filter(presence) %>% 
  group_by(id) %>% 
  summarise(
    Color = paste0(color, collapse = ", ")
  )

# Add the new column, and remove the temporary id
df <- df %>% 
  left_join(df_new_col, by = "id") %>% 
  select(-id)

我这样做是为了防止有一些行全部都是 FALSE。


0

另一种 dplyr 的方式:

library(dplyr)

df %>%
  rowwise %>%
  mutate(color = toString(names(.)[c_across(everything())])) %>%
  ungroup

输出:

# A tibble: 5 × 5
  red   yellow orange blue  color           
  <lgl> <lgl>  <lgl>  <lgl> <chr>           
1 FALSE FALSE  FALSE  TRUE  "blue"          
2 TRUE  FALSE  FALSE  TRUE  "red, blue"     
3 FALSE FALSE  FALSE  TRUE  "blue"          
4 FALSE FALSE  FALSE  FALSE ""              
5 FALSE TRUE   TRUE   FALSE "yellow, orange"

0

我们可以使用 tidyverse

library(dplyr)
library(tidyr)
 df1 %>% 
  mutate(across(red:blue, ~ case_when(.x ~ cur_column()))) %>%
  unite(color, red:blue, na.rm = TRUE, sep = ", ", remove = FALSE)

-输出

           color  red yellow orange blue
1           blue <NA>   <NA>   <NA> blue
2      red, blue  red   <NA>   <NA> blue
3           blue <NA>   <NA>   <NA> blue
4                <NA>   <NA>   <NA> <NA>
5 yellow, orange <NA> yellow orange <NA>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接