我像 a 一样创建自己的函数,但它在运行时遇到了一些问题。
# condition and target_col must be str,
modify<-function(data,target_col,condition,value){
row_index <- which(eval(parse(text=condition))
data[row_index,target_col]<-value
return(data)
}
我想实现这个效果
这是我的数据
library(dplyr)
data<-data.frame(c=c("z","x","c","e"),a=c(1,2,3,4),b=(1,2,3,4))
cond_context<-c("z","c")
这是我以前用过的,但我认为不是有效和优雅的,它会改变一整行
result<-data%>%mutate(a=ifelse(c%in%cond_context,1,a))
这是使用我的功能
result<-data%>%modify("a","data$c%in%cond_cotext",1)
我的函数有两个问题
#first i can't use %>% smoothly
data%>%mutate(d=1)%>%modify("a","data$d%in%cond_context",1)
this is wrong, function can't find data$d obj,
i must use like this
data<-data%>%mutate(d=1)
data<-data%>%modify("a","data$d%in%cond_context",1)
# sencond i can't when i use this in a function ,it report cat't find cond_context,i don't know how to solve this proble, but it is ok run step by step on environment.
我的理想函数是这样的:
result<-data%>%modify(a,c%in%cond_cotext,1)
Mybe我的描述太乏味了,所以我的最后一个问题是如何实现我理想的修改函数,或者有一些有用的库功能可以直接使用
多谢
这应该有效:
library(rlang)
library(magrittr)
#' @param data dataframe
#' @param cond_col character. Name of column containing condition is based on.
#' @param cond vector. Vector containing values to check for in code{cond_col}.
#' @param target_col character. Name of column to modify.
#' @param value vector of length 1. Value to replace with in column code{target_col}.
modify <- function(data, cond_col, cond, target_col, value){
init_factor <- is.factor(data[[target_col]])
if(init_factor) data[,target_col] <- as.character(data[[target_col]])
data %<>%
dplyr::mutate(!!target_col := ifelse(!!ensym(cond_col) %in% cond,
value,
.data[[target_col]]))
if(init_factor) data[,target_col] <- as.factor(data[[target_col]])
data
}
例如,下面是运行函数的代码,输出如下:
test_df <- data.frame(x = 1:2, y = "a")
modify(test_df, "x", 1, "y", "b")
x y
1 1 b
2 2 a
如您所见,最初列y
只有"a"
的值。应用modify
后,当x
的值为1
时,它的值为"b"
,但当x
不1
时,它保留其初始值。
请注意,#' @param
行不是函数定义的一部分。它们只是指示函数中的每个参数所采用的内容。例如,#' @param data dataframe
表示参数data
接受类dataframe
的输入。