【问题标题】:insert column names in dplyr在 dplyr 中插入列名
【发布时间】:2020-08-23 05:30:30
【问题描述】:

假设我有一个包含很多列的数据框:var1、...、var100,还有一个相同长度的匹配命名向量。
我想创建一个函数,如果在数据框中有 NA,它将从命名向量中选择数据。这是我到目前为止写的:

data %>% 
  mutate(var1 = ifelse(is.na(var1), named_vec["var1"], var1),
         var2 = ifelse(is.na(var2), named_vec["var2"], var2),
         ...)

它可以工作,但是如果我有 100 个变量,那么写这么多条件是非常不切实际的。然后我尝试了这个:

data %>% 
   mutate_if(~ifelse(is.na(.x), named_vec[colnames(.x)], .x))

Error in selected[[i]] <- eval_tidy(.p(column, ...)) : 
  more elements supplied than there are to replace

但是这不起作用。 dplyr 中有没有办法提取列名我可以切片命名向量吗?

这里有一个数据小例子来试试

data <- data.frame(var1 = c(1, 1, NA, 1),
                   var2 = c(2, NA, NA, 2),
                   var3 = c(3, 3, 3, NA))

named_vec <- c("var1" = 1, "var2" = 2, "var3" = 3)

【问题讨论】:

  • 不工作代码的结果也会有帮助

标签: r dplyr names


【解决方案1】:

使用coalesce 可能更容易做到这一点

library(dplyr)
library(purrr)
library(stringr)
nm1 <- str_c('var', 1:3)
data[nm1] <- map_dfc(nm1, ~ coalesce(data[[.x]], named_vec[.x]))
data
#  var1 var2 var3
#1    1    2    3
#2    1    2    3
#3    1    2    3
#4    1    2    3

或者如果我们复制“named_vec”,

data[] <-  coalesce(as.matrix(data), named_vec[col(data)])

另一种选择是转换为“长”格式,然后对“值”列执行left_joincoalesce,然后重新整形为“宽”格式

library(tidyr)
data %>%
   mutate(rn = row_number()) %>%
   pivot_longer(cols = -rn) %>% 
   left_join(enframe(named_vec), by = 'name') %>%
   transmute(rn, name, value = coalesce(value.x, value.y)) %>% 
   pivot_wider(names_from = name, values_from = value) %>% 
   select(-rn)

【讨论】:

  • 谢谢。我已经解决了data %&gt;% replace_na(as.list(named_vec))
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-14
  • 1970-01-01
  • 2021-09-21
  • 2021-03-28
  • 2018-02-27
  • 2020-09-21
相关资源
最近更新 更多