考虑以下问题data.table.第一个定义了一组具有每个组'x'的起始位置和结束位置的区域:
library(data.table)
d1 <- data.table(x = letters[1:5], start = c(1,5,19,30, 7), end = c(3,11,22,39,25))
setkey(d1, x, start)
# x start end
# 1: a 1 3
# 2: b 5 11
# 3: c 19 22
# 4: d 30 39
# 5: e 7 25
Run Code Online (Sandbox Code Playgroud)
第二个数据集具有相同的分组变量"x",并在每个组中定位"pos":
d2 <- data.table(x = letters[c(1,1,2,2,3:5)], pos = c(2,3,3,12,20,52,10))
setkey(d2, x, pos)
# x pos
# 1: a 2
# 2: a 3
# 3: b 3
# 4: b 12
# …Run Code Online (Sandbox Code Playgroud) setkey()各州的文件:
setkey()对data.table进行排序并将其标记为已排序.排序列是关键.密钥可以是任何顺序的任何列.列始终按升序排序.该表由参考更改 ...(强调添加)
我总是将其解释为setkey()创建索引,而不是物理地重新排列数据表的行(类似于索引数据库表).但是如果这是真的那么删除密钥(使用setkey(DT,NULL)),应该删除索引并将数据表恢复为原始的未排序顺序.这不是发生的事情:
library(data.table)
DT <- data.table(a=3:1, b=1:3, c=5:7); DT
a b c
1: 3 1 5
2: 2 2 6
3: 1 3 7
setkey(DT,a); DT
a b c
1: 1 3 7
2: 2 2 6
3: 3 1 5
setkey(DT,NULL)
a b c
1: 1 3 7
2: 2 2 6
3: 3 1 5
Run Code Online (Sandbox Code Playgroud)
所以有两个问题:
1:如果行重新排列(排序),那么"按引用更改"的含义是什么意思?
2:究竟setkey(DT,NULL)做了什么?
我是R的新手,这是我关于stackoverflow的第一个问题。
我在尝试
示例数据:
id code date_down date_up
1: 1 p 2019-01-01 2019-01-02
2: 1 f 2019-01-02 2019-01-03
3: 2 f 2019-01-02 2019-01-02
4: 2 p 2019-01-03 <NA>
5: 3 p 2019-01-04 <NA>
6: 4 <NA> 2019-01-05 2019-01-05
7: 5 f 2019-01-07 2019-01-08
8: 5 p 2019-01-07 2019-01-08
9: 5 p 2019-01-09 2019-01-09
10: 6 f 2019-01-10 2019-01-10
11: 6 p 2019-01-10 2019-01-10
12: 6 p 2019-01-10 2019-01-11
Run Code Online (Sandbox Code Playgroud)
我想做的是
iddate_up第一行,code …我已经在Internet和SO上进行了一些搜索,以寻找对data.table如此快的方法的介绍或分析,但是我只发现了很多(非常有用的)手册,而没有深入了解编程内容。(我或多或少地完全data.table陷入了无法找到的已发表论文的地步,甚至找不到JStatSoft的文章。)
我上过算法课,所以我知道排序和链表以及二叉树等,但是我不想作任何业余猜测(尤其是当我向学术界人士解释为什么使用它是一个好主意时) )。谁能提供简短的主题摘要以及参考资料?这个问题引用了一个很酷的幻灯片演示文稿,但是信息是分块的(甚至文档setkey()也没有引用data.table,而是转到Wikipedia)。
我所寻找的东西,既没有源代码,不是维基百科主题的列表,而是一个理想的“官方”,来源答案(从而使之规范,可能有很大的帮助与所有 的 问题, 轨道 围绕这个话题)。
(如果有一份技术文件,在那里我可以举这个(在这将是巨大citation()的data.table仅仅是手动的,但是当然这并不是问题,只要SO关注直接相关的。)
我试图找到通过几个数字列对大型数据集进行子集化的最快方法.正如data.table所承诺的那样,二进制搜索所花费的时间比矢量扫描要快得多.但是,二进制搜索需要预先执行setkey.正如您在此代码中看到的那样,需要非常长的时间!考虑到这段时间后,矢量扫描要快得多:
set.seed(1)
n=10^7
nums <- round(runif(n,0,10000))
DT = data.table(s=sample(nums,n), exp=sample(nums,n),
init=sample(nums,n), contval=sample(nums,n))
this_s = DT[0.5*n,s]
this_exp = DT[0.5*n,exp]
this_init = DT[0.5*n,init]
system.time(ans1<-DT[s==this_s&exp==this_exp&init==this_init,4,with=FALSE])
# user system elapsed
# 0.65 0.01 0.67
system.time(setkey(DT,s,exp,init))
# user system elapsed
# 41.56 0.03 41.59
system.time(ans2<-DT[J(this_s,this_exp,this_init),4,with=FALSE])
# user system elapsed
# 0 0 0
identical(ans1,ans2)
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?我已经阅读了data.table常见问题解答等.任何帮助将不胜感激.
非常感谢.
是否可以在保留其键order的data.table同时存储行?
可以说我有以下虚拟表:
library(data.table)
dt <- data.table(id=letters[1:6],
group=sample(c("red", "blue"), replace=TRUE),
value.1=rnorm(6),
value.2=runif(6))
setkey(dt, id)
dt
id group value.1 value.2
1: a blue 1.4557851 0.73249612
2: b red -0.6443284 0.49924102
3: c blue -1.5531374 0.72977197
4: d red -1.5977095 0.08033604
5: e blue 1.8050975 0.43553048
6: f red -0.4816474 0.23658045
Run Code Online (Sandbox Code Playgroud)
我想存储这个表,以便按行排序group,按value.1降序排列,即:
> dt[order(group, value.1, decreasing=T),]
id group value.1 value.2
1: f red -0.4816474 0.23658045
2: b red -0.6443284 0.49924102
3: d red -1.5977095 0.08033604 …Run Code Online (Sandbox Code Playgroud) 我是一名教师,并希望正确使用该data.table软件包在R日志文件中自动评分学生答案,即correct如果学生回答某个特定问题,则添加一个列,该答案是该问题的正确答案,否则为0.如果每个问题只有一个答案,我可以很容易地做到这一点,但如果一个问题有多个可能的答案(问题及其可能的正确答案存储在另一个表中),我会被绊倒
以下是MWE:
set.seed(123)
question_table <- data.table(id=c(1,1,2,2,3,4),correct_ans=sample(1:4,6,replace = T))
log <- data.table(student=sample(letters[1:3],10,replace = T),
question_id=c(1,1,1,2,2,2,3,3,4,4),
student_answer= c(2,4,1,3,2,4,4,5,2,1))
Run Code Online (Sandbox Code Playgroud)
我的问题出在什么是正确的data.table使用方式ifelse中j,特别是如果我们依赖于另一个表?
log[,correct:=ifelse(student_answer %in%
question_table[log$question_id %in% id]$correct_ans,1,0)]
Run Code Online (Sandbox Code Playgroud)
如下所示,问题1和2都有多个可能的正确答案.
> question_table
id correct_ans
1: 1 2
2: 1 4
3: 2 2
4: 2 4
5: 3 4
6: 4 1
Run Code Online (Sandbox Code Playgroud)
虽然正确的列是在没有错误的情况下计算出来的,但有些事情是不对的:例如,当student b答案有问题时,即使答案不正确,他也会获得正确的分数.只有correct列的一些条目是关闭的,这使我相信有些东西我没有得到变量的作用域.
> log
student question_id student_answer correct
1: b 1 2 1
2: c 1 4 1
3: …Run Code Online (Sandbox Code Playgroud) 我需要将两个数据集与壁橱时间戳一起加入。第一个数据集是来自移动应用程序的日记数据集:
df1 <- data.frame(stringsAsFactors=FALSE,
datetime = c("2019-03-19T13:26:52Z", "2019-03-19T13:26:19Z",
"2019-03-19T13:23:46Z", "2019-03-19T13:22:20Z",
"2019-03-19T13:09:56Z", "2019-03-19T13:06:04Z", "2019-03-19T13:05:21Z",
"2019-03-19T13:04:37Z", "2019-03-19T12:47:28Z",
"2019-03-19T12:46:42Z"),
transport = c("Trainride", "Trainride", "Trainride", "Trainride",
"Trainride", "Trainride", "Trainride", "Trainride",
"Trainride", "Trainride"),
id = c("5-3", "5-3", "5-3", "5-3", "5-3", "5-3", "5-3", "5-3", "5-3",
"5-3"),
disc = c("start", "stop", "start", "stop", "start", "stop", "start",
"stop", "start", "stop")
)
# datetime dttr object
df1 <- df1 %>%
mutate(datetime = lubridate::as_datetime(datetime))
Run Code Online (Sandbox Code Playgroud)
这里:
datetime transport id disc
1 2019-03-19 13:26:52 Trainride 5-3 start
2 2019-03-19 …Run Code Online (Sandbox Code Playgroud) 假设我有两个相等长度的逻辑向量.以简单的方式计算混淆矩阵:
c(sum(actual == 1 & predicted == 1),
sum(actual == 0 & predicted == 1),
sum(actual == 1 & predicted == 0),
sum(actual == 0 & predicted == 0))
Run Code Online (Sandbox Code Playgroud)
需要扫描矢量4次.
是否可以一次性完成?
PS.我尝试过table(2*actual+predicted),table(actual,predicted)但两者显然都慢得多.
PPS.速度不是我的主要考虑因素,我对理解语言更感兴趣.
当data.table在数字矢量上设置辅助索引时,似乎不允许使用on =语法对行进行子设置。但是,我在文档中看不到任何表明仅字符列可以作为辅助索引的内容。on =语法是否仅限于字符列?
library(data.table)
dt <- data.table(A = 1:10, B = letters[1:10])
setindex(dt, A, B)
dt[on = "B", "c"]
dt[on = "A", 3]
Run Code Online (Sandbox Code Playgroud)