函数中的 dplyr NSE 模式:嵌套条件
dplyr NSE mode in a function: nested conditions
objective 用于转换数据框的列。这是示例:
df <- data.frame( fact=c("dog",2,"NA",0,"cat",1,"Cat"),
value=c(4,2,6,0,9,1,3) ); df$fact <- as.factor(df$fac)
func <- function(data,fac,val){
data <- data %>%
mutate_(fac= interp(~tolower(fac), fac=as.name(fac)) ) %>%
mutate_(val= interp(~ifelse(fac=='cat',1*val,
ifelse(fac=='dog',2*val,0)), fac=as.name(fac), val=as.name(val)))
return(data) }
来电:
new.df <- func(df,"fact","value")
fact value fac val
1 dog 4 dog 8
2 2 2 2 0
3 NA 6 na 0
4 0 0 0 0
5 cat 9 cat 9
6 1 1 1 0
7 Cat 3 cat 0
存在 2 个问题:(1)- 关联到 "Cat" 的值是假的;应该是3*1=3
(2)- 理想情况下调用 returns 原始 data.frame df
以及转换后的 fact
和 value
变量。
有什么想法吗?谢谢大家。
编辑:请注意 df
有另一列 third
,它应该不受对 fact
和 value
。
在 OP 的代码中,'val' 是基于未修改的 'fact' 列创建的。如果我们使用第一个 mutate_
的修改后的 'fac',我们不需要 as.name(fac)
.
library(lazyeval)
library(dplyr)
func <- function(data,fac,val){
data <- data %>%
mutate_(fac= interp(~tolower(fac), fac=as.name(fac))) %>%
mutate_(val= interp(~ifelse(fac=='cat',1*val,
ifelse(fac=='dog',2*val,0)), val=as.name(val)))
return(data) }
func(df, 'fact', 'value')
# fact value fac val
#1 dog 4 dog 8
#2 2 2 2 0
#3 NA 6 na 0
#4 0 0 0 0
#5 cat 9 cat 9
#6 1 1 1 0
#7 Cat 3 cat 3
如果我们只需要 return 修改的列,请使用 transmute_
func1 <- function(data,fac,val){
data <- data %>%
transmute_(fac= interp(~tolower(fac), fac=as.name(fac)),
val= interp(~ifelse(fac=='cat',1*val,
ifelse(fac=='dog',2*val,0)), val=as.name(val)))
return(data) }
func1(df, 'fact', 'value')
# fac val
#1 dog 8
#2 2 0
#3 na 0
#4 0 0
#5 cat 9
#6 1 0
#7 cat 3
如果您想 return 原始 列(可能包括 data.frame 中的其他列)使用原始名称,您可以稍微使用使用 mutate_each
而不是 mutate
的不同 dplyr 方法:
library(lazyeval)
library(dplyr)
func <- function(data,fac,val) {
data %>%
mutate_each_(interp(~tolower(var), var = as.name(fac)), fac) %>%
mutate_each_(interp(~ifelse(col =='cat', var, ifelse(col == 'dog',2*var, 0)),
var=as.name(val), col = as.name(fac)), val)
}
使用函数:
func(df, "fact", "value")
# fact value
#1 dog 8
#2 2 0
#3 na 0
#4 0 0
#5 cat 9
#6 1 0
#7 cat 3
如果您的数据中有您希望保留在其中的其他列(而由于 transmute
,将使用 akrun 的方法删除它们),就会证明与 akruns 答案的区别:
df$some_column <- letters[1:7] # add a new column
其他列现在在使用该函数后保留在您的数据中,修改后的列保留其原始名称:
func(df, "fact", "value")
# fact value some_column
#1 dog 8 a
#2 2 0 b
#3 na 0 c
#4 0 0 d
#5 cat 9 e
#6 1 0 f
#7 cat 3 g
objective 用于转换数据框的列。这是示例:
df <- data.frame( fact=c("dog",2,"NA",0,"cat",1,"Cat"),
value=c(4,2,6,0,9,1,3) ); df$fact <- as.factor(df$fac)
func <- function(data,fac,val){
data <- data %>%
mutate_(fac= interp(~tolower(fac), fac=as.name(fac)) ) %>%
mutate_(val= interp(~ifelse(fac=='cat',1*val,
ifelse(fac=='dog',2*val,0)), fac=as.name(fac), val=as.name(val)))
return(data) }
来电:
new.df <- func(df,"fact","value")
fact value fac val
1 dog 4 dog 8
2 2 2 2 0
3 NA 6 na 0
4 0 0 0 0
5 cat 9 cat 9
6 1 1 1 0
7 Cat 3 cat 0
存在 2 个问题:(1)- 关联到 "Cat" 的值是假的;应该是3*1=3
(2)- 理想情况下调用 returns 原始 data.frame df
以及转换后的 fact
和 value
变量。
有什么想法吗?谢谢大家。
编辑:请注意 df
有另一列 third
,它应该不受对 fact
和 value
。
在 OP 的代码中,'val' 是基于未修改的 'fact' 列创建的。如果我们使用第一个 mutate_
的修改后的 'fac',我们不需要 as.name(fac)
.
library(lazyeval)
library(dplyr)
func <- function(data,fac,val){
data <- data %>%
mutate_(fac= interp(~tolower(fac), fac=as.name(fac))) %>%
mutate_(val= interp(~ifelse(fac=='cat',1*val,
ifelse(fac=='dog',2*val,0)), val=as.name(val)))
return(data) }
func(df, 'fact', 'value')
# fact value fac val
#1 dog 4 dog 8
#2 2 2 2 0
#3 NA 6 na 0
#4 0 0 0 0
#5 cat 9 cat 9
#6 1 1 1 0
#7 Cat 3 cat 3
如果我们只需要 return 修改的列,请使用 transmute_
func1 <- function(data,fac,val){
data <- data %>%
transmute_(fac= interp(~tolower(fac), fac=as.name(fac)),
val= interp(~ifelse(fac=='cat',1*val,
ifelse(fac=='dog',2*val,0)), val=as.name(val)))
return(data) }
func1(df, 'fact', 'value')
# fac val
#1 dog 8
#2 2 0
#3 na 0
#4 0 0
#5 cat 9
#6 1 0
#7 cat 3
如果您想 return 原始 列(可能包括 data.frame 中的其他列)使用原始名称,您可以稍微使用使用 mutate_each
而不是 mutate
的不同 dplyr 方法:
library(lazyeval)
library(dplyr)
func <- function(data,fac,val) {
data %>%
mutate_each_(interp(~tolower(var), var = as.name(fac)), fac) %>%
mutate_each_(interp(~ifelse(col =='cat', var, ifelse(col == 'dog',2*var, 0)),
var=as.name(val), col = as.name(fac)), val)
}
使用函数:
func(df, "fact", "value")
# fact value
#1 dog 8
#2 2 0
#3 na 0
#4 0 0
#5 cat 9
#6 1 0
#7 cat 3
如果您的数据中有您希望保留在其中的其他列(而由于 transmute
,将使用 akrun 的方法删除它们),就会证明与 akruns 答案的区别:
df$some_column <- letters[1:7] # add a new column
其他列现在在使用该函数后保留在您的数据中,修改后的列保留其原始名称:
func(df, "fact", "value")
# fact value some_column
#1 dog 8 a
#2 2 0 b
#3 na 0 c
#4 0 0 d
#5 cat 9 e
#6 1 0 f
#7 cat 3 g