有条件地排除使用dplyr::mutate()计算的行

有条件地排除使用dplyr::mutate()计算的行,r,dplyr,conditional-statements,R,Dplyr,Conditional Statements,我在一个TIBLE中填充一个新列,方法是在另一列中获取正元素的日志,同时不计算负值。我尝试使用if_else、ifelse和case_when从评估中排除负值,但没有成功 library(dplyr) my_df <- tibble(n=c(-2,-1,0,1,2,3)) my_df %>% mutate(log_n = if_else(n > 0, log(n), NA_real_)) 按预期工作,但抛出有关log函数生成的NaNs的警告: 如前所述,使用虚拟列可以避免这种

我在一个TIBLE中填充一个新列,方法是在另一列中获取正元素的日志,同时不计算负值。我尝试使用if_else、ifelse和case_when从评估中排除负值,但没有成功

library(dplyr)
my_df <- tibble(n=c(-2,-1,0,1,2,3))
my_df %>% mutate(log_n = if_else(n > 0, log(n), NA_real_))
按预期工作,但抛出有关
log
函数生成的
NaNs
的警告:

如前所述,使用虚拟列可以避免这种行为:

my_df  %>% 
group_by(xx= n <= 0) %>% 
mutate(test = ifelse(xx, NA_real_, log(n))) %>%
ungroup %>% 
select(-xx)
my_df%>%
分组依据(xx=n%
变异(测试=ifelse(xx,NA_real,log(n)))%>%
解组%>%
选择(-xx)

是否有更简单的方法只计算正值?

警告是由
log
正确生成的,因为
if_-else
true
false
参数计算整个表达式(在控制台中键入
if-else
,不带括号查看或查看).换句话说,该函数不计算
log(x)
仅适用于条件为真的那些值;它对所有值进行计算,然后仅返回条件为真的值。因此,当对所有负值计算log时,您会收到警告。它与
mutate
没有任何关系,具体而言,它只是显示它调用的函数中的警告;您可以看到是通过尝试在简单向量而不是数据帧列上调用日志

我认为为了避免这种情况(没有
suppressWarnings
或异常处理),您需要在计算
log
之前删除负值。您可以内联执行此操作,也可以使用一个小的辅助函数

库(dplyr)
my_df#A tibble:6 x 3
#>n log\n log\u安静
#>            
#>1-2NA
#>2-1NA
#>3 0-Inf-Inf
#> 4     1    0         0    
#> 5     2    0.693     0.693
#> 6     3    1.10      1.10

该警告由(v0.3.0)于2020-09-08创建。

该警告由
log
正确生成,因为
if_else
计算整个表达式的
true
false
参数(在控制台中键入
if_else
,不带括号查看或查看).换句话说,该函数不计算
log(x)
仅适用于条件为真的那些值;它对所有值进行计算,然后仅返回条件为真的值。因此,当对所有负值计算log时,您会收到警告。它与
mutate
没有任何关系,具体而言,它只是显示它调用的函数中的警告;您可以看到是通过尝试在简单向量而不是数据帧列上调用日志

我认为为了避免这种情况(没有
suppressWarnings
或异常处理),您需要在计算
log
之前删除负值。您可以内联执行此操作,也可以使用一个小的辅助函数

库(dplyr)
my_df#A tibble:6 x 3
#>n log\n log\u安静
#>            
#>1-2NA
#>2-1NA
#>3 0-Inf-Inf
#> 4     1    0         0    
#> 5     2    0.693     0.693
#> 6     3    1.10      1.10

由(v0.3.0)于2020年9月8日创建,因为似乎
如果_else
没有涵盖这一点,您可以做一个数学技巧:

my_df %>% 
   mutate(log_n = NA^(n < 0) * log(abs(n)))
# A tibble: 6 x 2
      n    log_n
  <dbl>    <dbl>
1    -2   NA    
2    -1   NA    
3     0 -Inf    
4     1    0    
5     2    0.693
6     3    1.10 
my_df%>%
变异(log_n=NA^(n<0)*log(abs(n)))
#一个tibble:6x2
n log\n
1-2 NA
2-1 NA
3 0-Inf
4     1    0    
5     2    0.693
6     3    1.10 
或者你可以:

my_df %>% 
   mutate(log_n = log(`is.na<-`(n, n < 0)))
# A tibble: 6 x 2
      n    log_n
  <dbl>    <dbl>
1    -2   NA    
2    -1   NA    
3     0 -Inf    
4     1    0    
5     2    0.693
6     3    1.10 
my_df%>%

mutate(log_n=log(`is.na因为似乎
如果_else
没有涵盖这一点,您可以做一个数学技巧:

my_df %>% 
   mutate(log_n = NA^(n < 0) * log(abs(n)))
# A tibble: 6 x 2
      n    log_n
  <dbl>    <dbl>
1    -2   NA    
2    -1   NA    
3     0 -Inf    
4     1    0    
5     2    0.693
6     3    1.10 
my_df%>%
变异(log_n=NA^(n<0)*log(abs(n)))
#一个tibble:6x2
n log\n
1-2 NA
2-1 NA
3 0-Inf
4     1    0    
5     2    0.693
6     3    1.10 
或者你可以:

my_df %>% 
   mutate(log_n = log(`is.na<-`(n, n < 0)))
# A tibble: 6 x 2
      n    log_n
  <dbl>    <dbl>
1    -2   NA    
2    -1   NA    
3     0 -Inf    
4     1    0    
5     2    0.693
6     3    1.10 
my_df%>%

mutate(log_n=log(`is.nay)你想避免警告吗?是的,我想,我已经编辑了文本来澄清这一点使用
if\u else(n>0,log(n),NA\u real)
你不能有
log(0)
所以你需要做
而不是
=
log(0)生成-Inf;这在我的情况下不是问题。仍然编辑代码以避免混淆您想避免警告吗?是的,我编辑了文本以澄清此问题。如果使用
其他(n>0,log(n),NA\u real)
您不能使用
日志(0)
,因此您需要执行
而不是
=
日志(0)生成-Inf;这在我的情况下不是问题。仍在编辑代码以避免混淆您的第一个建议非常有创意,非常适合这种情况。谢谢!您的第一个建议非常有创意,非常适合这种情况。谢谢!谢谢!我肯定会在未来使用任何一个建议的解决方案!我肯定会使用任何一个建议的解决方案未来的ested解决方案