下面是关于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 ]
注意:此答案的第(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=rowpos
和by=1:NROW(dt)
版本与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都不熟悉,所以我希望能就我发现的一个问题提供意见。我正在处理一个数据表,其中一列是冒号分隔的格式字符串,作为其他冒号分隔列中值的图例。为了解析它,我必须首先将其拆分为它的组件,然后搜索我需要稍后索引值字符