当前位置: 首页 > 知识库问答 >
问题:

数据中的行操作。使用“by=.I”的表格`

文彭祖
2023-03-14

下面是关于data.table中的行操作的一个很好的SO解释

我想到的一个替代方法是为每一行使用一个唯一的< code>id,然后使用< code>by参数应用一个函数。像这样:

library(data.table)

dt <- data.table(V0 =LETTERS[c(1,1,2,2,3)],
                 V1=1:5,
                 V2=3:7,
                 V3=5:1)

# create a column with row positions
dt[, rowpos := .I]

# calculate standard deviation by row
dt[ ,  sdd := sd(.SD[, -1, with=FALSE]), by = rowpos ] 

问题:

>

  • 有没有好的理由不使用这种方法?也许还有其他更有效的选择?

    为什么使用< code>by =。我不一样了?

    < code>dt[,sdd := sd(。SD[,-1,with=FALSE]),by =。I ]

  • 共有1个答案

    柯波峻
    2023-03-14

    注意:此答案的第(3)节于2019年4月更新,因为随着时间的推移,data.table发生了许多变化,使原始版本过时。此外,使用参数with=已从data.table的所有实例中删除,因为它已被弃用。

    1)至少对于< code>rowsums示例来说,不使用它的一个原因是性能和创建不必要的列。与下面的选项f2相比,它的速度快了将近4倍,并且不需要rowpos列(请注意,原始问题使用< code>rowSums作为示例函数,这是本部分答案的回应。OP后来编辑了问题以使用不同的功能,与本答案的第3部分更相关`):

    dt <- data.table(V0 =LETTERS[c(1,1,2,2,3)], V1=1:5, V2=3:7, V3=5:1)
    f1 <- function(dt){
      dt[, rowpos := .I] 
      dt[ ,  sdd := rowSums(.SD[, 2:4]), by = rowpos ] }
    f2 <- function(dt) dt[, sdd := rowSums(.SD), .SDcols= 2:4]
    
    library(microbenchmark)
    microbenchmark(f1(dt),f2(dt))
    # Unit: milliseconds
    #   expr      min       lq     mean   median       uq      max neval cld
    # f1(dt) 3.669049 3.732434 4.013946 3.793352 3.972714 5.834608   100   b
    # f2(dt) 1.052702 1.085857 1.154132 1.105301 1.138658 2.825464   100  a 
    

    2)关于你的第二个问题,虽然< code>dt[,sdd := sum(。SD[,2:4]),by =。I]不起作用,< code>dt[,sdd := sum(。SD[,2:4]),by = 1:NROW(dt)]完美工作。鉴于根据<代码>?data.table "。I是等于seq_len(nrow(x))”的整数向量,人们可能期望它们是等价的。然而,不同之处在于< code >。I在< code>j中使用,而不是在< code>by中使用。注意<代码>的值。I是在data.table中内部计算的,因此不能像在< code>by=中那样预先作为参数值传递。我。

    还可以预期<code>by=.I<code>会抛出一个错误。但这不会发生,因为加载<code>数据。表包创建一个对象。I数据中的。可从全局环境访问的表命名空间,其值为NULL。您可以通过键入<code>来测试这一点。I在命令提示符下。(注意,这同样适用于.SD.EACHI.N、GRP、和。BY

    .I
    # Error: object '.I' not found
    library(data.table)
    .I
    # NULL
    data.table::.I
    # NULL
    

    这样做的结果是 by 的行为 = 。I 等效于 = 空

    3) 虽然我们已经在第1部分中看到,在<code>行和

    这里提供了参考性信息,将by=rowposby=1:NROW(dt)版本与for 进行基准测试。我们发现在<code>for的循环之间,在时序上存在可忽略的差异。在没有任何性能差异的情况下, f。nrow可能更可取,但前提是更简洁,不创建不必要的列

    dt <- data.table(V0 = rep(LETTERS[c(1,1,2,2,3)], 1e3), V1=1:5, V2=3:7, V3=5:1)
    
    f.rowpos <- function() {
      dt[, rowpos := .I] 
      dt[,  sdd := sum(.SD[, 2:4]), by = rowpos ] 
    }
    
    f.nrow <- function() {
      dt[, sdd := sum(.SD[, 2:4]), by = seq_len(NROW(dt)) ]
    }
    
    f.forset<- function() {
      for (i in seq_len(NROW(dt))) set(dt, i, 'sdd', sum(dt[i, 2:4]))
    }
    
    microbenchmark(f.rowpos(),f.nrow(), f.forset(), times = 5)
    # Unit: milliseconds
    #       expr       min        lq      mean    median        uq       max neval
    # f.rowpos()  559.1115  575.3162  580.2853  578.6865  588.5532  599.7591     5
    #   f.nrow()  558.4327  582.4434  584.6893  587.1732  588.6689  606.7282     5
    # f.forset() 1172.6560 1178.8399 1298.4842 1255.4375 1292.7393 1592.7486     5
    

    因此,总之,即使在没有优化函数(例如rowSums)已经按行运行的情况下,也有使用rowpos列的替代方案,尽管速度不快,但不需要创建冗余列。

     类似资料:
    • 我在R中有两个数据表,如下: 具有列、、、,其中是主键,是次要键。 有列、、、、......、。这里是主键,因此每一行对应于唯一的,其他列名对应于中的辅助键。 我想在< code>DT_A中添加另一列,其中第I行包含表DT_B[sid_i,date_i]中的相应元素 下面是示例代码和所需输出: 虽然我当前的方法在这个小例子上有效,但我的实际DT_A有2000万行,这个方法完全挂在那里,我们可以使用

    • 创建表 查看表结构 查看表详细结构 修改表名 修改字段的数据类型 修改字段名 增加字段 删除字段 删除关联表 (1)删除表的外键约束 (2)删除没有被关联的普通表 (3)删除被其他表关联的父表 创建表: CREATE TABLE 表名 (属性名 数据类型 [完整性约束条件], 属性名 数据类型 [完整性约束条件], 属性名 数据类型 [完整性约束条件]) “完整性约束条件”是指指定某些字段的某些特

    • SQLAlchemy 1.4 / 2.0 Tutorial 此页是 SQLAlchemy 1.4/2.0教程 . 上一页: 使用数据 |下一步: |next| 使用ORM进行数据操作 上一节 使用数据 仍然从核心的角度关注SQL表达式语言,以便在主要的SQL语句结构中提供连续性。本节将构建 Session 以及它如何与这些结构相互作用。 先决条件部分 -本教程以ORM为重点的部分建立在本文档前面两

    • 我有需求,比如需要使用数据编织找到两个日期之间的差异,输入和输出都是XML格式。 这两个日期格式yyyy.mm.dd和输出日期格式必须像mm.dd.yy或mm.dd.yyyy. 请帮助我,谢谢

    • 以下语句都可以直接在InfluxDB的Web管理界面中调用 # 创建数据库 CREATE DATABASE "db_name" # 显示所有数据库 SHOW DATABASES # 删除数据库 DROP DATABASE "db_name" # 使用数据库 USE mydb # 显示该数据库中的表 SHOW MEASUREMENTS # 创建表 # 直接在插入数据的时候指定表名(weathe

    • (我很抱歉我的例子过于简单,我将尝试解决这个问题,并以更方便的格式格式化我更相关的示例,以便直接复制到R中。特别是,有多个值列,以及前面一些不需要解析的其他信息的列。 我对R和data.table都不熟悉,所以我希望能就我发现的一个问题提供意见。我正在处理一个数据表,其中一列是冒号分隔的格式字符串,作为其他冒号分隔列中值的图例。为了解析它,我必须首先将其拆分为它的组件,然后搜索我需要稍后索引值字符