我有一个庞大的数据集(100多个变量超过200万行;下面是一个小样本)。对于每个subj_trial
组,我想找到包含在" .wav"中的每个唯一变量的第一个匹配项。在message
。它应该只包含,而不是结束(即* .wav),因为某些行在message
字段中有一堆信息(示例中没有图示,抱歉)。
输出只有这三列的data.frame是可以的,但不是必需的。我稍后需要使用timestamp
列进行分析。
我发现了这个问题:Extract rows for the first occurrence of a variable in a data frame,但对于我的生活,我无法用这个例子来适应我的。
以下是一些示例数据:
subj_trial message timestamp
1 1_1 message 459 755616
2 1_1 . 755618
3 1_1 test1.wav 755662
4 1_1 . 765712
5 1_1 test1.wav 767918
6 1_2 . 769342
7 1_2 test2.wav 775662
8 1_2 . 786412
9 1_2 test2.wav 797460
10 1_2 . 807626
11 1_3 test3.wav 817794
12 1_3 warning 11 827960
13 2_1 message 481 817313
14 2_1 test1.wav 817347
15 2_1 . 834959
16 2_1 test1.wav 855007
17 2_1 . 880107
18 2_2 . 895723
19 2_2 test2.wav 922671
20 2_2 . 958003
21 2_2 test2.wav 994385
22 2_3 . 1016217
23 2_3 test3.wav 1036899
24 2_3 . 1047331
25 2_3 test3.wav 1142527
这是我在这里处理的一个非常小的例子。对于每个subj_trial
组,可能有3000行,并且有超过700个组。
这是我想要拥有的一个例子。
subj_trial message timestamp
1 1_1 test1.wav 755662
2 1_2 test2.wav 775662
3 1_3 test3.wav 817794
4 2_1 test1.wav 817347
5 2_2 test2.wav 922671
6 2_3 test3.wav 1036899
通过这样做,我已经弄明白了如何在整个数据集中获取message
中的唯一值:
unique_message <- df[match(unique(df$message), df$message),]
但是我无法弄清楚如何按小组来做。我也尝试在group_by
包中使用dplyr
,但也无法使用window.location.href = '/yourpage'
。朋友,请怜悯和指路。谢谢!
答案 0 :(得分:2)
同样使用data.table,但使用更简洁的表述:
setDT(DT)
DT[,.SD[grep("\\.wav",message)[1]],by=subj_trial]
修改:根据以下评论的建议,
DT[grepl("\\.wav", message), .SD[1], by=subj_trial]
可能更快,因为它使用布尔逻辑和优化的I
子集。
.SD是一个data.table,包含每个组的DT数据子集,不包括by(或keyby)中使用的任何列。
by
有点像SQL中的group by
运算符。它指定分组列。
grep(pattern, x)
返回pattern
中x
的所有匹配项的索引,其中x
是向量。\\
之前的.wav
会阻止grep将.
视为特殊字符(在grep的解析中,未转义的.
表示'任何')。
vector_name[1]
返回名为vector_name的向量的第一个元素。它可以在函数的结果上调用,例如上面的grep。
data.table
公式为DT[I,J,by]
-I
是子集或联接,J
是要执行的操作,by
是分组元素。在我们的例子中,I
被忽略(因此领先,
)因为我们想要处理整个集合。J
是所有.SD列的操作。 by是您希望结果分组的列。
答案 1 :(得分:1)
使用$("#email").on('submit', function(e){
e.preventDefault();
var input = $(this).val();
var match = input.match(/^\w+@atlanticbay.com$/i);
if(typeof match != 'null'){
console.log("we are good");
// add submit codes here..probably ajax
}
console.log("prevented");
});
:
data.table
答案 2 :(得分:1)
如果您有兴趣,这里还有一个dplyr
解决方案:
dat %>%
filter(grepl("\\.wav", message)) %>%
group_by(subj_trial) %>%
top_n(n=1, wt=desc(timestamp))
首先,将数据过滤到消息列中包含* .wav的数据。然后按主题试验对数据进行分组,并返回具有最小时间戳的最高结果。这假设您需要最小时间戳,而不一定是数据集中的第一个时间戳(即,如果首先出现时间戳较大的记录,则不会返回)。我不清楚你在寻找什么,但也许在你的情况下没有区别。
由于我总是对data.table
和dplyr
方法之间的效率差异感到好奇,所以我做了microbenchmark
测试。看起来在这种情况下,data.table
具有轻微的速度优势:
library(microbenchmark)
library(data.table)
set.seed(1)
dat <- data.frame(subj_trial=paste0(sample(1:20,1e6,replace=TRUE),"_",sample(1:20,1e6,replace=TRUE)),
message=sample(c(".wav","others"), 1e6, replace=TRUE),
timestamp=round(seq(from=1000, to=9142527, length.out = 1e6)))
dat2 <- dat
setDT(dat2)
microbenchmark({dat %>%
filter(grepl("\\.wav", message)) %>%
group_by(subj_trial) %>%
top_n(1, wt=desc(timestamp))},
{dat2[grepl("\\.wav", message), .SD[1], by=subj_trial]})
Unit: milliseconds
expr
dat %>% filter(grepl("\\\\.wav", message)) %>% group_by(subj_trial) %>% top_n(1, wt = desc(timestamp))
dat2[grepl("\\\\.wav", message), .SD[1], by = subj_trial]
min lq mean median uq max neval cld
332.9693 357.7426 387.2245 367.6443 380.9935 637.9223 100 b
263.0292 272.8627 293.4976 281.4568 285.7699 582.9954 100 a