我的R脚本从用户那里获得三个输入,这些输入被读入var1,var2和var3。
我正在尝试对数据帧执行简单的子集操作。我的想法是伪代码 如下所示:
subset_data_frame<- dat[ dat[[var1]] var2 var3 , ]
where var1= column name from dat
var2= can be any of the logical operator like '==', '>', '<' etc.
var3= numeric value
但是由于我使用var2中的逻辑运算符的方式,这不起作用。
请建议我另外一种解决此问题的方法。
答案 0 :(得分:1)
如果用户将这些变量作为字符输入,则您需要创建和评估呼叫。以下是使用mtcars
数据集的示例:
var1 <- "mpg"
var2 <- ">"
var3 <- "30"
expr <- call(var2, mtcars[[var1]], as.numeric(var3))
## or you could also construct a function call with substitute()
# expr <- substitute(
# FUN(mtcars[[column]], value),
# list(FUN = as.name(var2), column = var1, value = as.numeric(var3))
# )
现在我们创建了一个未经评估的电话expr
,然后可以使用eval
评估
mtcars[eval(expr),]
# mpg cyl disp hp drat wt qsec vs am gear carb
# Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
# Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
# Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
# Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
答案 1 :(得分:0)
(1)正则表达式
首先需要根据用户的输入构建一个合法的表达式,然后将该字符串作为命令进行评估。这是一个POC。
> cmd <- "iris[iris$1% 2% 3%,]"
> columnname <- readline("columnname:")
columnname:Sepal.Length
> operator <- readline("operator:")
operator:<
> value <- readline("value:")
value:5
> cmd <- gsub("1%", columnname, cmd)
> cmd <- gsub("2%", operator, cmd)
> cmd <- gsub("3%", value, cmd)
> cmd
[1] "iris[iris$Sepal.Length < 5,]"
> eval(parse(text=cmd))
Sepal.Length Sepal.Width Petal.Length Petal.Width Species
2 4.9 3.0 1.4 0.2 setosa
3 4.7 3.2 1.3 0.2 setosa
4 4.6 3.1 1.5 0.2 setosa
7 4.6 3.4 1.4 0.3 setosa
9 4.4 2.9 1.4 0.2 setosa
10 4.9 3.1 1.5 0.1 setosa
12 4.8 3.4 1.6 0.2 setosa
13 4.8 3.0 1.4 0.1 setosa
...
(2)Metaprogram
Here是一个章节 - 来自HadleyWickham先进的R的表达。在那里,他解释了如何编程&#34; program&#34;的详细说明。
答案 2 :(得分:0)
Step1。制作所需表达式的字符向量:
expr<-paste(dat[[var1]],var2,var3,sep = " ")
Step2。评估表达式以制作逻辑向量
myLogicalVec<-sapply(expr, function(x) eval(parse(text=x)))
Step3。在数据框中使用该逻辑向量
dat[myLogicalVec,]
我对R来说相当新,并且可以采用最佳方式。这有点类似于Richard Scriven的答案,但我的思考过程就是这样。