我有一个(显然很简单)的问题,但我似乎找不到解决它的方法。这是基本设置:
IDS<-c('ID1','ID2','ID3','ID4')
CNT<-1:10;
d<-data.table(merge(CNT,IDS),key=c('y','x'))
setnames(d,colnames(d),c('CNT','ID'))
r<-c(1,1.1,0.9,1.2)
d[,SIGNAL:=r[which(IDS==ID)]*c(62.2,62.2,61.4,61.4,63.4,66.1,62.6,62.6,59.5,57.5),by=ID]
(示例将在 ID1 上,r 变量只是为了提供一些可变性)
The question is the following: I'd like to add two columns which will hold the 'range' within which the signal is fluctuating. The range is a parameter (in this example it is 6 [signal-3, signal+3]. Also the range should remain linear until the signal 'crosses' the bounds (up or down). Then it should reset.
在信号跨越之前设定的界限之前,该范围不应改变。让我研究一下我给你的例子:
对于 ID1 的情况,我希望这个范围是:
CNT ID SIGNAL LOWER.BOUND UPPER.BOUND
1: 1 ID1 62.2 59.2 65.2
2: 2 ID1 62.2 59.5 65.2
3: 3 ID1 61.4 59.2 65.2
4: 4 ID1 61.4 59.2 65.2
5: 5 ID1 63.4 59.2 65.2
6: 6 ID1 66.1 63.1 69.1
7: 7 ID1 62.6 59.6 65.6
8: 8 ID1 62.6 59.6 65.6
9: 9 ID1 59.5 56.5 62.5
10: 10 ID1 57.5 56.5 62.5
所以你看,每当信号跨越之前的边界(上限或下限)时,就会重新计算边界。
我已经尝试了几种方法来诚实地告诉你,但我总是发现一个小问题!事实上,我必须不断检查以前的界限并不是最简单的工作......
- 我尝试根据第一个边界设置边界并进行调整 每当有越界的时候,但这行不通 在CNT=9的情况下,ID=ID1。信号是 59.5 如果我有 传播(na.locf-ed)第一个值,然后是本例中的边界 本来是59.2-65.2,但我需要56.5-62.5。
- 我尝试计算每个信号相应的界限,但随后 边界不是“线性”的。
- 然后我尝试逐行执行此操作,但没有成功。
- 然后我把我的电脑弄坏了。那也没用:)
如果这个问题太……毫无意义,我深表歉意。如果您觉得它很有趣并且想要做出贡献,请告诉我,我会尝试重新措辞/添加更多信息。
非常感谢您的帮助
PS 使用 data.table 的原因是行数约为数百万,而 data.table 是迄今为止我使用过的库中性能最好的。我更愿意坚持使用 data.table。
N
最佳答案
为了避免伤脑筋,我会用 Rcpp 编写一个简单的函数:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
List funcpp(NumericVector x, double r) {
const int n(x.size());
NumericVector lwr(n), upr(n);
lwr[0] = x[0]-r;
upr[0] = x[0]+r;
for (int i=1; i<n; i++)
{
if (x[i]<lwr[i-1] || x[i]>upr[i-1])
{
lwr[i] = x[i]-r;
upr[i] = x[i]+r;
}
else
{
lwr[i] = lwr[i-1];
upr[i] = upr[i-1];
}
}
return Rcpp::List::create(_["lwr"] = lwr,
_["upr"] = upr);
}
在data.table中使用它:
d[, c("lwr", "upr") := funcpp(SIGNAL,3), by=ID]
CNT ID SIGNAL lwr upr
1: 1 ID1 62.20 59.20 65.20
2: 2 ID1 62.20 59.20 65.20
3: 3 ID1 61.40 59.20 65.20
4: 4 ID1 61.40 59.20 65.20
5: 5 ID1 63.40 59.20 65.20
6: 6 ID1 66.10 63.10 69.10
7: 7 ID1 62.60 59.60 65.60
8: 8 ID1 62.60 59.60 65.60
9: 9 ID1 59.50 56.50 62.50
10: 10 ID1 57.50 56.50 62.50
11: 1 ID2 68.42 65.42 71.42
12: 2 ID2 68.42 65.42 71.42
13: 3 ID2 67.54 65.42 71.42
14: 4 ID2 67.54 65.42 71.42
15: 5 ID2 69.74 65.42 71.42
16: 6 ID2 72.71 69.71 75.71
17: 7 ID2 68.86 65.86 71.86
18: 8 ID2 68.86 65.86 71.86
19: 9 ID2 65.45 62.45 68.45
20: 10 ID2 63.25 62.45 68.45
21: 1 ID3 55.98 52.98 58.98
22: 2 ID3 55.98 52.98 58.98
23: 3 ID3 55.26 52.98 58.98
24: 4 ID3 55.26 52.98 58.98
25: 5 ID3 57.06 52.98 58.98
26: 6 ID3 59.49 56.49 62.49
27: 7 ID3 56.34 53.34 59.34
28: 8 ID3 56.34 53.34 59.34
29: 9 ID3 53.55 53.34 59.34
30: 10 ID3 51.75 48.75 54.75
31: 1 ID4 74.64 71.64 77.64
32: 2 ID4 74.64 71.64 77.64
33: 3 ID4 73.68 71.64 77.64
34: 4 ID4 73.68 71.64 77.64
35: 5 ID4 76.08 71.64 77.64
36: 6 ID4 79.32 76.32 82.32
37: 7 ID4 75.12 72.12 78.12
38: 8 ID4 75.12 72.12 78.12
39: 9 ID4 71.40 68.40 74.40
40: 10 ID4 69.00 68.40 74.40
CNT ID SIGNAL lwr upr
关于r - 根据先前的值确定 data.table 列的边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22077621/