使用dplyr转换所有编码为" Y" /" N"为TRUE / FALSE

时间:2016-07-27 16:50:21

标签: r dplyr

我有以下数据

df <- data.frame(A = 1:3, YN_B = c('Y', 'N', 'N'), YN_C = c('N', 'N', 'Y'))

这些带有c值的变量(&#39; Y&#39;,&#39; N&#39;)对我来说并不是很有用。对于&#39; Y&#39;它们将被编码为TRUE更有用。对于N&#39;和FALSE有用的是,Y / N列的命名方式可以让我以编程方式找到它们。我认为在这种情况下mutate_if应该是一个帮助。

我正在尝试用mutate_if实现这个目标,我之前没有使用过它,但是它并没有完全正常工作。这是我的尝试

df %>% mutate_if(matches('^YN'), .funs = funs(function(x) x == 'Y'))
Error in get(as.character(FUN), mode = "function", envir = envir) : 
  object 'p' of mode 'function' was not found

我哪里错了?

4 个答案:

答案 0 :(得分:7)

matches返回指定列位置的整数,但mutate_if需要布尔值作为谓词。要使用matches,您可以使用mutate_at代替:

library(dplyr)
df %>% mutate_at(vars(matches('^YN')), funs(. == 'Y'))
#   A  YN_B  YN_C
# 1 1  TRUE FALSE
# 2 2 FALSE FALSE
# 3 3 FALSE  TRUE

以下是matches如何运作的示例:

matches('^YN', vars = c("A", "YN_B"))
# [1] 2

在此处为mutate_if添加另一个案例,我们可以根据列类型改变列:

lapply(df, class)
# $A
# [1] "numeric"

# $YN_B
# [1] "character"

# $YN_C
# [1] "character"

df %>% mutate_if(is.character, funs(. == 'Y'))
#   A  YN_B  YN_C
# 1 1  TRUE FALSE
# 2 2 FALSE FALSE
# 3 3 FALSE  TRUE

答案 1 :(得分:3)

你不需要plyr。使用reshape2包融合数据框并重新计算

df.long <- within(melt(df, 'A'), value <- value == 'Y')

然后把它扔掉

df.new <- dcast(df.long, A ~ variable)

现在你明白了:

> df.new
  A  YN_B  YN_C
1 1  TRUE FALSE
2 2 FALSE FALSE
3 3 FALSE  TRUE

答案 2 :(得分:1)

 >df %>% mutate(YN_B=(YN_B=="Y"),YN_C=(YN_C=="Y"))

          A  YN_B  YN_C
   (int) (lgl) (lgl)
1     1  TRUE FALSE
2     2 FALSE FALSE
3     3 FALSE  TRUE

答案 3 :(得分:0)

我们可以使用data.table

library(data.table)
i1 <- grep("YN", names(df))
setDT(df)[, paste0(i1, "L") := lapply(.SD, `==`, "Y"), .SDcols = i1]