R 如何添加“data.table”中计算变量的数据量最小的条件`

R 如何添加“data.table”中计算变量的数据量最小的条件`,r,data.table,R,Data.table,我有两个数据帧。第一个df总结了在超时(DateTime)对一种鱼类的几个个体(ID)的检测。例如: options("digits.secs" = 3) df<- data.frame(DateTime=c("2017-08-05 14:03:55.300","2017-08-05 16:18:12.100","2017-08-05 20:34:31.540","2017-08-05 16:18:14.355","2017-08-05 20:34:33.605"), ID= c

我有两个数据帧。第一个
df
总结了在超时(
DateTime
)对一种鱼类的几个个体(
ID
)的检测。例如:

options("digits.secs" = 3)

df<- data.frame(DateTime=c("2017-08-05 14:03:55.300","2017-08-05 16:18:12.100","2017-08-05 20:34:31.540","2017-08-05 16:18:14.355","2017-08-05 20:34:33.605"),
    ID= c("A","B","C","B","C"))

df
                 DateTime ID
1 2017-08-05 14:03:55.300  A
2 2017-08-05 16:18:12.100  B
3 2017-08-05 20:34:31.540  C
4 2017-08-05 16:18:14.355  B
5 2017-08-05 20:34:33.605  C
我使用下面的代码计算
df
中的变量
VeDBA
RMS
。我使用
Activity
中的数据来计算它们,并将这些变量添加到数据框
df
。作为总结,对于每行
df
数据,我使用2秒的数据计算
VeDBA
RMS
(这是22行,因为我在数据帧
活动中每秒有11个数据
)从
活动
数据框,使用数据框
df
DateTime
作为开始时间

library(data.table)
setDT(df)[, DateTime := as.POSIXct(DateTime, format=fmt, tz="UTC")][,
    c("start", "end") := .(DateTime, DateTime+2)]
setDT(Activity)[, DateTime := as.POSIXct(DateTime, format=fmt, tz="UTC")]

df<- Activity[df, on=.(ID, DateTime>=start, DateTime<=end),
    by=.EACHI, .(
        DateTime=i.DateTime,
        ID=i.ID, 
        VeDBA=sum(sqrt(x^2 + y^2 + z^2)) / .N,
        RMS=sqrt((sum(x^2) + sum(y^2) + sum(z^2)) / .N))][, 
            (1L:3L) := NULL][]
我想得到这个:

df
                  DateTime ID     VeDBA       RMS
1: 2017-08-05 14:03:55.299  A 0.9919576 1.0264458
2: 2017-08-05 16:18:12.099  B NA        NA        # Between 16:18:12.099 and 16:18:14.099 there is only 10 data instead of 22
3: 2017-08-05 20:34:31.539  C 0.9294209 0.9764383
4: 2017-08-05 16:18:14.355  B NA        NA
5: 2017-08-05 20:34:33.605  C 1.0041628 1.0395891

有人知道如何修改我使用的
数据.table
代码以获得那些
NAs

如果
.N
低于给定的阈值,下面的修改将返回
NA

n_min <- 14L
Activity[df, on = .(ID, DateTime >= start, DateTime <= end),
         by = .EACHI, .(
           DateTime = i.DateTime,
           ID = i.ID,
           .N,  # inserted just to verify the result, to be omitted in production code
           VeDBA = if (.N < n_min) NA_real_ else sum(sqrt(x ^ 2 + y ^ 2 + z ^ 2)) / .N,
           RMS = if (.N < n_min) NA_real_ else sqrt((sum(x ^ 2) + sum(y ^ 2) + sum(z ^ 2)) / .N)
         )][,
            (1L:3L) := NULL][]
请注意,插入列
N
只是为了验证结果。还请注意,尽管使用了
set.seed(100)
创建数据,但输出与OP的预期结果不同


if()
可以在这里使用,因为每个
.EACHI
组只有一个
.N
值。

我当时不在电脑旁,但你似乎可以从
rle
和/或
数据中得到提升。table::rleid
Hi@PavoDive。我不知道你到底是什么意思。我没有使用太多的
数据.table
。如果您能详细说明我如何做我在帖子中解释的事情,我将不胜感激。。。。提前谢谢!!谢谢@Uwe!!我在运行代码时收到错误消息
未使用的参数
。我想这是因为
NA_real\u
没有在代码中定义,不是吗?如果没有,可能是什么?在等待你的回答时,我问你其他的疑问。关于你的结果和我的不同,我对
NA
的理解是错误的,因为第四行应该对
VeDBA
RMS
使用
NA
(我在我的帖子中对其进行了修改)。关于
VeDBA
RMS
I gues值的差异,这是因为即使在使用
set.seed()
之后,您的数据帧
活动
和我的活动也不同。几天前我发现,如果你的R版本低于3.16,那么
sample()
会产生不同的数字。。。为了验证这一点,我在帖子中显示了我的
活动
数据帧的头部。你有相同的数字吗?如果其中一个数据帧不是data.table对象,我会看到此错误消息。我发现了问题@Uwe。确切地说,您没有在代码中添加从data.frame到data.table的转换,我也没有意识到。如果在您的代码之前运行
setDT(df)[,DateTime:=as.POSIXct(DateTime,format=fmt,tz=“UTC”)][,c(“开始”,“结束”):=(DateTime,DateTime+2)]
setDT(Activity)[,DateTime:=as.POSIXct(DateTime,format=fmt,tz=“UTC”)]
,那么它工作得非常好。再次感谢!!很抱歉造成了误会。我没有发布全部代码,只是发布了需要修改的部分。关于不同R版本上的
set.seed()
:我使用RStudio云和
sessionInfo()
说它是R版本3.6.0(2019-04-26),平台:x86_64-pc-linux-gnu(64位),运行于:ubuntu16.04.6 LTS,…,随机数生成:RNG:mersene Twister Normal:Inversion示例:舍入。不幸的是,我得到了不同的数据运行您的启动代码。
sessionInfo()
为您返回了什么?
df
                  DateTime ID     VeDBA       RMS
1: 2017-08-05 14:03:55.299  A 0.9919576 1.0264458
2: 2017-08-05 16:18:12.099  B NA        NA        # Between 16:18:12.099 and 16:18:14.099 there is only 10 data instead of 22
3: 2017-08-05 20:34:31.539  C 0.9294209 0.9764383
4: 2017-08-05 16:18:14.355  B NA        NA
5: 2017-08-05 20:34:33.605  C 1.0041628 1.0395891
n_min <- 14L
Activity[df, on = .(ID, DateTime >= start, DateTime <= end),
         by = .EACHI, .(
           DateTime = i.DateTime,
           ID = i.ID,
           .N,  # inserted just to verify the result, to be omitted in production code
           VeDBA = if (.N < n_min) NA_real_ else sum(sqrt(x ^ 2 + y ^ 2 + z ^ 2)) / .N,
           RMS = if (.N < n_min) NA_real_ else sqrt((sum(x ^ 2) + sum(y ^ 2) + sum(z ^ 2)) / .N)
         )][,
            (1L:3L) := NULL][]
                  DateTime ID  N     VeDBA       RMS
1: 2017-08-05 14:03:55.299  A 22 0.8777660 0.9181305
2: 2017-08-05 16:18:12.099  B 10        NA        NA
3: 2017-08-05 20:34:31.539  C 22 0.8807835 0.9383084
4: 2017-08-05 16:18:14.355  B 10        NA        NA
5: 2017-08-05 20:34:33.605  C 22 1.0587765 1.1023549