基于dplyr中的向量创建新列

3

使用dplyr,可以轻松使用mutate创建新列:

df <- data.frame(v1 = 1:3, v2 = c('a','b','c'))
> mutate(df, newcol = NA)
  v1 v2 newcol
1  1  a     NA
2  2  b     NA
3  3  c     NA

我们也可以使用向量和 mutate_at ( 在这里展示:这里) 来创建多个新列:

> cnames <- c('newcol1', 'newcol2', 'newcol3')
> mutate_at(df, cnames, funs(log(v1)))
  v1 v2   newcol1   newcol2   newcol3
1  1  a 0.0000000 0.0000000 0.0000000
2  2  b 0.6931472 0.6931472 0.6931472
3  3  c 1.0986123 1.0986123 1.0986123

有没有一种简单的方法使用 dplyr 将这些新列初始化为 NA?

例如,mutate_at(df, cnames, funs(v1 * NA)) 可以得到期望的结果,但似乎有些间接。我想要的是类似于以下方式的内容:

mutate_at(df, cnames, funs(. = NA)) # Error: Can't create call to non-callable object

我们不需要知道其他列的名称。

(我知道可以使用df[ , cnames] <- NA来简单解决,但我正在寻找一种使用dplyr函数的解决方案)


编辑:

在使用较新版本的dplyr时,示例变为:

mutate_at(df, all_of(cnames), funs(log(v1)))

不确定是否是一个bug。你不需要在那里使用“v1”。任何数字都足够,例如1或0mutate_at(df, cnames, funs( NA * 0))甚至可以添加“+”。 - akrun
当我尝试您的示例时,我收到以下错误消息: “错误:无法对不存在的列进行子集。 x 列 newcol1 不存在。” 显然,向量cnames中的值应该已经存在。您是如何让您的代码工作的?我正在使用dplyr版本0.8.3和R版本3.6.3。 - Adriaan Nering Bögel
@AdriaanNeringBögel,更新 - 现在我认为你需要使用 all_of - C. Braun
@C.Braun,它仍然不起作用。如果需要all_of,RStudio会发出警告。 - Adriaan Nering Bögel
1个回答

5

你可以这样做。

library(dplyr)
df %>% 
 `is.na<-`(cnames)
#  v1 v2 newcol1 newcol2 newcol3
#1  1  a      NA      NA      NA
#2  2  b      NA      NA      NA
#3  3  c      NA      NA      NA

我希望你能够熟练使用dplyr,并且理解%>%操作符的含义。 ;)

1
这很简单,但我觉得应该有一种使用 dplyr 函数的方法来完成这个任务(更多是个人偏好,不使用反引号函数)。我注意到 df %>% '[<-'(, cnames, NA) 也可以工作,但在我看来,两者都会打断 dplyr 链的流程。 - C. Braun
2
@C.Braun 你可能知道 magrittr 包提供了一组别名来处理这种情况,可以参考 ?magrittr::add。你也可以自己定义别名,使得管道操作更加愉悦,例如 set_NA <- \is.na<-`; df %>% set_NA(cnames)`。 - markus

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