请考虑以下最小的工作示例:

library(magrittr) # for the %>% pipe 
library(data.table) 

# test data.table contains common_column and two others
test_dt <- data.table(test_column_one = c(1, 2, 3), test_column_two = c("x","y","z"), common_column = c("ID1", "ID2", "ID3") ) 

# some other data.table that contains common_column
other_dt <- data.table( additional_info = c("US", "US", "GB"), common_column = c("ID1", "ID2", "ID3")) 

example_function <- function(dt_column){
  # does some things on the data tables based on the column parameter passed
  merged_dt <- merge(other_dt, test_dt[,.(common_column, dt_column)], by = "common_column") %>%
    .[order(dt_column),] # order by the dt_column
  return(merged_dt)
} 

# calling the example function
example_function(test_dt$test_column_one)

如何将代码修改为:

  1. 相反,可以使用列名指定字符串作为参数
  2. 能够传递带有列名的向量或字符串列表

我希望尽可能避免for循环,并利用优化的data.table语法.

我try 使用特定于data.table的unlist()..语法,但不知何故总是收到奇怪的错误消息,并且不确定如何继续.

推荐答案

创建列名的矢量

有三种方法可以做到这一点,我在下面阐述了这一点,但我认为最清楚的方法是创建一个列向量来使用..语法.

example_function <- function(dt_column, dt1 = other_dt, dt2 = test_dt) {
    cols_to_merge <- c("common_column", dt_column)
    merged_dt <- merge(
        dt1,
        dt2[, ..cols_to_merge],
        by = "common_column"
    )

    # No need to pipe - see explanation below
    setorderv(merged_dt, dt_column)
    return(merged_dt)
}

example_function("test_column_one")
#    common_column additional_info test_column_one
#           <char>          <char>           <num>
# 1:           ID1              US               1
# 2:           ID2              US               2
# 3:           ID3              GB               3

与其他方法的比较

让我们假设我们想要从mtcars中 Select mpg和一个动态列,在本例中恰好是wt.

mtcars <- as.data.table(mtcars)
col_of_interest <- "wt"

我认为基本上有三种data.table种方法.

  1. 同上.作为data.table v1.10.2 (31 Jan 2017) docs个国家:

j是一个前缀为..的符号时,它将在调用范围中查找,其值将被视为列名或数字.

cols  <- c("mpg", col_of_interest)
mtcars[, ..cols]
  1. data.table v1.11.0 (01 May 2018)年来:

这个[..]前缀现在扩展到出现在j=中的所有符号

mtcars[, c("mpg", ..col_of_interest)]
  1. 正如Using .SD for Data Analysis个小插曲中所述.
cols <- c("mpg", col_of_interest)
mtcars[, .SD, .SDcols = cols]

就我个人而言,我认为创建列名向量是最清晰的方法,但第二种方法意味着少创建一个变量.第三种方法是最向后兼容的.

A note on using order()

文件规定,..只能在j中工作.以下陈述等同:

mtcars[order(mpg)]
mtcars[order(mpg),]
mtcars[i = order(mpg),]

由于order(mpg)是提供给i的参数,如果我们设置为x <- "mpg",则执行mtcars[order(..x)]是无效的.

如果你必须使用order(),这里有一些方法可以做到这一点:

# Use ..
mtcars[order(mtcars[, ..x])]
# Use `[[`
mtcars[order(mtcars[[x]])]
# Use .SD
mtcars[mtcars[, sapply(.SD, order), .SDcols = x]]
# Use get() (this has been retired in favour of `env` - see comments)
mtcars[order(get(x))]

然而,它们创建了数据的副本,它们并不美观,而且它们也是有限的(如果您想按两列排序怎么办?)

与通过管道和子集创建副本相比,通常更可取的做法是使用setorderv()就地修改,从而利用data.table的效率,如我在上面提供的example_function()中:

setorderv(mtcars, x)

这也很容易扩展到希望按多个列排序的情况.

R相关问答推荐

按块将载体转换为矩阵-reshape

在ggplot的注释表格中突出显示最大值

ggplot geom_smooth()用于线性回归虚拟变量-没有回归线

将复杂的组合列表转换为数据框架

Highcharter多次钻取不起作用,使用不同方法

如何删除gggvenn与gggplot绘制的空白?

如何从R中的字符串元素中减go 一个数字?

将向量组合到一个数据集中,并相应地命名行

R根据条件进行累积更改

标识R中多个列中缺少的唯一值

如何在R forestplot中为多条垂直线分配唯一的 colored颜色 ?

如何使这些react 表对象相互独立?

将项粘贴到向量中,并将它们分组为x的倍数,用空格分隔

如何在使用箭头R包(箭头::OPEN_DATASSET)和dplyr谓词时编写具有整齐计算的函数?

如何在R中改变fviz_pca_biplot中圆的边界线的 colored颜色 ?

如何在AER::ivreg中指定仪器?

将数据从一列转换为按组累计计数的单个虚拟变量

使用R、拼图和可能的网格包绘制两个地块的公共垂直线

如果缺少时间,如何向日期-时间列添加时间

Data.table条件合并