假设我在一个data.table个对象中创建一个新列:

require(data.table)
data(iris)
dt.iris <- data.table(iris)

dt.iris[,shortSpecies:=substr(Species,1,5)]

现在,我不想直接使用:=来执行此操作,而是希望有一个函数,该函数将创建列的代码作为参数,然后对其求值.我最终得到了这样的结果:

make_new_col <- function(inputDT, newColName, construction){
  set(
    x = inputDT, 
    j = newColName, 
    value=eval(expr = parse(text = construction), envir=inputDT)
    )
}

dt.iris <- make_new_col(
  inputDT = dt.iris, 
  newColName = 'shortSpecies', 
  construction = 'substr(Species,1,5)'
)

这是可行的,但现在我想添加一个条件,即使其等同于dt.iris[Sepal.Length>5,shortSpecies:=substr(Species,1,5)].我需要以某种方式将条件传递到set()i=部分进行判断,但我找不到有效的解决方案.

推荐答案

您可以提供一个标准条件if condmissing.

> library(data.table)
> make_new_col3 <- function(inputDT, cond, newColName, construction) {
+   stopifnot(ncol(inputDT) > 0)
+   if (missing(cond)) cond <- "`mode<-`(inputDT[[1]], 'logical')"
+   set(
+     x=inputDT, 
+     i=(w <- which(eval(parse(text=cond), envir=inputDT))),
+     j=newColName, 
+     value=eval(parse(text=construction), envir=inputDT[w, ])
+   )
+ }

> dt.iris <- make_new_col3(
+   inputDT=dt.iris, 
+   cond='Sepal.Length > 5',
+   newColName='shortSpecies', 
+   construction='substr(Species, 1, 5)'
+ )
> head(dt.iris)
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species shortSpecies
1:          5.1         3.5          1.4         0.2  setosa        setos
2:          4.9         3.0          1.4         0.2  setosa         <NA>
3:          4.7         3.2          1.3         0.2  setosa         <NA>
4:          4.6         3.1          1.5         0.2  setosa         <NA>
5:          5.0         3.6          1.4         0.2  setosa         <NA>
6:          5.4         3.9          1.7         0.4  setosa        setos

> dt.iris <- make_new_col3(
+   inputDT=dt.iris, 
+   # cond='Sepal.Length > 5',
+   newColName='shortSpecies', 
+   construction='substr(Species, 1, 5)'
+ )
> head(dt.iris)
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species shortSpecies
1:          5.1         3.5          1.4         0.2  setosa        setos
2:          4.9         3.0          1.4         0.2  setosa        setos
3:          4.7         3.2          1.3         0.2  setosa        setos
4:          4.6         3.1          1.5         0.2  setosa        setos
5:          5.0         3.6          1.4         0.2  setosa        setos
6:          5.4         3.9          1.7         0.4  setosa        setos

Data:

dt.iris <- as.data.table(iris)

R相关问答推荐

R -列表元素中所有命名项的总和

按自定义数字模式对变量名称排序

如何判断某列中由某些行组成的百分比

编辑文件后编辑RhandsonTable

如何编辑ggplot的图例字使用自定义对象(gtable)?'

为什么观察不会被无功值变化触发?

RStudio中相关数据的分组箱形图

如何直接从Fortran到R的数组大小?

当我们有多个特殊字符时,使用gsub删除名称和代码'

如果某些列全部为NA,则更改列

如何从R ggplot图片中获取SVG字符串?

通过在colname中查找其相应值来创建列

使用rvest从多个页面抓取时避免404错误

根据1个变量绘制 colored颜色 发散的 map ,由另一个变量绘制饱和度,ggplot2不工作

如何使用FormC使简单算术运算得到的数字是正确的?

根据r中另一个文本列中给定的范围对各列求和

按两个因素将观测值分组后计算单独的百分比

访问数据帧中未定义的列时出现R错误

分隔日期格式为2020年7月1日

策略表单连接两个非常大的箭头数据集,而不会 destruct 内存使用