2

我正在尝试更新我的以下代码,因为funs( MY_FUN )已软贬值。我知道应该替换它list( ~MY_FUN ),但这似乎不适用于我的代码。

这是我的数据框:

fake_data <- data.frame(var1 = rep("TEMP", times = 5),
                        var2 = rep("TEMP", times = 5),
                        var3 = c(1:5),
                        stringsAsFactors = FALSE)

lookup_sub <- data.frame(var_names = c("var1", "var2", "var3"),
                         example_value = c("a", "b", "c"),
                         stringsAsFactors = FALSE)

以下代码行有效并且完全符合我的要求:

library(tidyverse)
library(rlang)
fake_data %>%
        mutate_if(.predicate = rlang::as_function(function(x){identical("TEMP", unique(x))}),
                  .funs = funs(as.character((lookup_sub %>% filter(var_names == quo_name(quo(.))) %>% pull(example_value))[1])))

导致

  var1 var2 var3
1    a    b    1
2    a    b    2
3    a    b    3
4    a    b    4
5    a    b    5

但是使用未折旧参数将所有 NA 值提供给谓词中评估为 TRUE 的行

fake_data %>%
        mutate_if(.predicate = rlang::as_function(function(x){identical("TEMP", unique(x))}),
                  .funs = list(~as.character((lookup_sub %>% filter(var_names == quo_name(quo(.))) %>% pull(example_value))[1])))

这导致

  var1 var2 var3
1 <NA> <NA>    1
2 <NA> <NA>    2
3 <NA> <NA>    3
4 <NA> <NA>    4
5 <NA> <NA>    5

有人可以向我解释一下吗?我知道问题的发生是因为quo_name(quo(.))但我不知道如何解决它。谢谢!

4

1 回答 1

0

我认为前面的评论是对的,这肯定是 mutate_if 函数是如何构建的问题。我有另一个非常有趣的问题的例子 - 我相信 - 在当前的 mutate_if 框架内是不可能回答的。

考虑这个假数据

smooth_data <- data.frame(`s(gam_variable_1_output)` = c(1.004, 1.345, 1.460, 1.540),
                          `s(gam_variable_2_output)` = c(1, 1, 1, 1),
                          grouping_variable_1 = c(1,2,3,4),
                          grouping_variable_2 = c("a", "b", "a", "b"),
                          grouping_variable_3 = c(500, 500, 500, 500),
                          stringsAsFactors = FALSE) 

我想对所有平滑变量(以“s(”)开头的变量)应用一个函数,前提是该平滑变量的级别不是 1 个唯一值。

这应该通过以下方式完成

smooth_data %>%
mutate_if(.predicate = funs(length(unique(.)) != 1 & grepl("s\\(", quo_name(quo(.)))),
          ~2) # we'll use this for example

这样这应该会导致以下结果(我从 R 输出中删除了行名/数字)

s(gam_variable_1_output)
                       2
                       2
                       2
                       2
s(gam_variable_2_output)
                       1
                       1
                       1
                       1
grouping_variable_1       grouping_variable_2       grouping_variable_3
                  1                       "a"                       500
                  2                       "b"                       500
                  3                       "a"                       500
                  4                       "b"                       500

但该功能不起作用。如果我们想拆分谓词,那么我们会看到一些有趣的东西。

#### FIRST PART OF CONDITIONAL: only look at variables that arent a single value
## THIS WORKS
smooth_data %>% mutate_if(funs(length(unique(.)) != 1), ~2)
## ^ THAT IS THE SAME AS THIS; THIS WORKS
smooth_data %>% mutate_if(~length(unique(.)) != 1, ~2)
## THIS DOES NOT WORK
smooth_data %>% mutate_if(length(unique(.)) != 1, ~2)


#### SECOND PART OF CONDITIONAL: only look at variables that have name including `s(`
## THIS WORKS
smooth_data %>% mutate_if(grepl("s\\(", names(.)), ~2)

## THIS THROWS ERROR (BECAUSE OF `names(.)`)
smooth_data %>% mutate_if(~grepl("s\\(", names(.)), ~2)

## THIS DOES NOT WORK
smooth_data %>% mutate_if(~grepl("s\\(", quo_name(quo(.))), ~2)

## WHICH IS THE SAME AS THIS
smooth_data %>% mutate_if(funs(grepl("s\\(", quo_name(quo(.)))), ~2)

## AND THIS THROWS ERROR (BECAUSE IT NEEDS ~)
smooth_data %>% mutate_if(grepl("s\\(", quo_name(quo(.))), ~2)

这很有趣,因为它向我表明我的主要代码行无法运行,因为条件的第一部分需要在 funs() 设置中,而第二部分不能在 funs() 设置中。这不是问题的答案,但我认为它清楚地表明了问题mutate_if

于 2020-03-24T16:51:53.443 回答