我有一个关于在R中搜索值的问题,它实际上有点类似于昨天发布的问题(在这里给出:Searching a vector/data table backwards in R)除了我认为我的问题有点复杂(而且与我想做的事情相反),因为我对R很新,所以我不太清楚如何解决这个问题。
我有一个类似于下面给出的数据框,我希望找到我当前的索引值,其中Times
列与我当前时间不同而Midquote
列确实如此没有NA
值。
Index Times | Midquote
-----------------------------
1 10:30:45.58 | 5.319
2 10:30:45.93 | 5.323
3 10:30:45.104 | 5.325
4 10:30:45.127 | 5.322
5 10:30:45.188 | 5.325
6 10:30:45.188 | NA
7 10:30:45.212 | NA
8 10:30:45.231 | 5.321
9 10:30:45.231 | 5.321
如果我们从数据框的底部开始,并将其作为当前的'时间,这被发现是在索引9,Times
值10:30:45.231
和Midquote
值5.321
,然后如果我想找到第一个索引时间与我当前的时间不同,我们发现这被发现是索引7,其时间为10:30:45.212
(因为索引8具有相同的时间)。但我们也看到在索引7处Midquote
值为NA
,因此我现在必须再次检查数据框。索引6再次具有不同的时间(即10:30:45.188
),但它在NA
列中再次具有Midquote
值,因此再次向上移动到索引5,我们看到{{1 }}列与当前时间的时间不同(即Times
再次),10:30:45.188
值为Midquotes
。
因此,因为在索引5处的时间是5.325
(这与我当前时间10:30:45.188
不同)并且因为索引5处的10:30:45.231
值不是{{1我想获得输出' 5'因为它是满足两个标准的指数值。
我的问题是,有这样做的好方法吗?我很抱歉,如果这是一个简单的问题,我对R来说很新,我对使用数据框不太了解......
编辑:我还想最好不要在数据框中添加另一列(如上面提到的链接的最佳答案中所示),如果可能的话
答案 0 :(得分:2)
使用日期很难,尤其是小数秒。 如果你可以把时间转换成双打,那么就更容易使用了。 假设你的'时代''你可以使用这个
library(magrittr)
which(df$Times < df[9,1] & !is.na(df$Midquote)) %>% max()
which
给出了&#39;索引&#39;的向量。在哪里&#39;时代&#39;比9中的少得多,而且中等命中率为&#39;不是NA。 %>%
将向量发送到max()
,它给出了最高值。这是非常不优雅的,但将完成工作。
答案 1 :(得分:1)
如果我理解正确,请检查这是否是您期望的输出。
ind<-function(t,df){
ind<-t
while(t>1){
t=t-1
if((df$Times[t]!=df$Times[ind]) && (!is.na(df$Midquote[t]))){
return(t)
}
}
}
sapply((nrow(data):1),FUN = ind,data)
#[[1]]
#[1] 5
#[[2]]
#[1] 5
#[[3]]
#[1] 5
#[[4]]
#[1] 4
#[[5]]
#[1] 4
#[[6]]
#[1] 3
#[[7]]
#[1] 2
#[[8]]
#[1] 1
#[[9]]
#NULL
输出系列对应于从最后一行开始的data.frame的关联索引。
说明:ind
将行号的值作为当前行,而t
从ind-1
开始取值为df
。while
将整个data.frame作为输入,然后df$Times[t]
循环用于检查df$Midquote[t]
和sapply
的时间和中间值是否满足所需条件。如果是,则返回索引,否则循环继续,直到到达第一行。
不使用 ind(9,df)
[1] 5
表示特定的当前行:
class IService {
virtual void DoWork() = 0;
virtual bool IsRunning() = 0;
};
class ClientA : IService {
void DoWork() {
std::cout << "Work in progress inside A";
}
bool IsRunning() {
return true;
}
};
class ClientB : IService {
void DoWork() {
std::cout << "Work in progress inside B";
}
bool IsRunning() {
return true;
}
};
class Server {
IService* _service;
Server(IService* service) : _service(service)
{ }
// Error: this declaration has no storage class or type specifier
// Compiler: MSVC 2017
_service->DoWork();
};
答案 2 :(得分:1)
zip.AddFile()
解决方案,1行。
Data.table
修改强>
要删除索引列,您(至少)有两个选项
library(data.table)
dt <- data.table(Index = 1:9,
Times = c( '10:30:45.58', '10:30:45.93','10:30:45.104','10:30:45.127','10:30:45.188','10:30:45.188','10:30:45.212','10:30:45.231','10:30:45.231' ),
Midquote = c('5.319','5.323','5.325','5.322','5.325',NA,NA,'5.321','5.321')
)
> dt[ Times != Times[.N] & !is.na(Midquote), max(Index) ]
[1] 5
NB 您无法dt2 <- data.table(Times = c( '10:30:45.58', '10:30:45.93','10:30:45.104','10:30:45.127','10:30:45.188','10:30:45.188','10:30:45.212','10:30:45.231','10:30:45.231' ),
Midquote = c('5.319','5.323','5.325','5.322','5.325',NA,NA,'5.321','5.321'))
# Option 1 - create an id column on the fly (unfortunately data.table recalculate .I after evaluating the "where" clause... so you need to save it)
dt2[, cbind(.SD, id=.I)][ Times != Times[.N] & !is.na(Midquote), max(id) ]
# Option 2 - simply check the last position of where your condition is met
dt2[, max(which(Times != Times[.N] & !is.na(Midquote))) ]
,因为您可以拥有符合条件的第1,第2和第4条记录,nrow
会给出你3,这是错误的,因为第3行不匹配。
编辑2 (选项3不是正确)
nrow