r:除了循环似乎别无选择的情况

标签 r loops

我有一个数据集,其中包含许多试验的时间序列。在每次试验中,参与者可能会看目标图片 (trg)、竞争对手 (cmp) 或干扰物。试验的长度不同。这个小代码片段创建了一个示例时间序列。

sbj <- c(rep("s1",6),rep("s2",8))
trial <- c(rep(1,4),rep(2,2),rep(1,3),rep(2,5))
trg <- c(rep(0,3),1,0,1,c(rep(0,2),1,0,0,0,1,1))
cmp <- c(rep(0,3),0,1,0,c(rep(0,2),0,0,0,1,0,0))
dis <- c(rep(1,3),0,0,0,c(rep(1,2),0,1,1,0,0,0))
time<-c(seq(1,4),seq(1,2),seq(1,3),seq(1,5))
df<-data.frame(sbj,trial,time,trg,cmp,dis)
df

数据框看起来像这样:

#   sbj trial time trg cmp dis
1   s1     1    1   0   0   1
2   s1     1    2   0   0   1
3   s1     1    3   0   0   1
4   s1     1    4   1   0   0
5   s1     2    1   0   1   0
6   s1     2    2   1   0   0
7   s2     1    1   0   0   1
8   s2     1    2   0   0   1
9   s2     1    3   1   0   0
10  s2     2    1   0   0   1
11  s2     2    2   0   0   1
12  s2     2    3   0   1   0
13  s2     2    4   1   0   0
14  s2     2    5   1   0   0

现在我想做的是创建记录,其中 trg、cmp 和 dis 的值是他们在受试者中每次试验的总和——参与者看了他们多少帧——另一个是将其转换为比例查看每个对象的时间步长。例如,对于第一个受试者的第一次试验,有 4 个时间步长。目标固定为 1 个时间步长,因此其总和为 1,其比例为 0.25。我正在寻找的结果对于总和来说是这样的:

#  sbj trial trgSum cmpSum disSum
1  s1     1      1      0      3
2  s1     2      1      1      0
3  s2     1      1      0      2
4  s2     2      2      1      2

像这样的比例:

#  sbj trial trgProp cmpProp disProp
1  s1     1    0.25     0.0    0.75
2  s1     2    0.50     0.5    0.00
3  s2     1    0.33     0.0    0.67
4  s2     2    0.40     0.2    0.40

这很容易实现,遍历主题和试验的所有独特组合。但在真实的数据集中,对几十个受试者进行数百次试验,每次试验有数百个时间步,因此循环需要很长时间。谁能建议一种避免循环的方法?

谢谢!

** 编辑 ** 我有一个后续问题,它揭示了我薄弱的 R 技能。实际的数据框有一些额外的因素。例如,如果我们将 df 修改为具有其他几个因素:

grp <- c(rep("g1",6), rep("g2",8))
cnd <- c(rep("c1",4),rep("c2",2),rep("c1",3),rep("c4",5))
#
sbj <- c(rep("s1",6),rep("s2",8))
trial <- c(rep(1,4),rep(2,2),rep(1,3),rep(2,5))
trg <- c(rep(0,3),1,0,1,c(rep(0,2),1,0,0,0,1,1))
cmp <- c(rep(0,3),0,1,0,c(rep(0,2),0,0,0,1,0,0))
dis <- c(rep(1,3),0,0,0,c(rep(1,2),0,1,1,0,0,0))
time<-c(seq(1,4),seq(1,2),seq(1,3),seq(1,5))
df<-data.frame(sbj,grp,cnd,trial,time,trg,cmp,dis)
df

聚合和 dplyr 方法由于 df 中存在因素而命中错误,或者设法将“总和”形式应用于没有意义的变量。 data.table 解决方案有效,但删除了 grp 和 cnd 列。有没有办法让它工作,然后以某种方式将它与适当的 grp 和 cnd 值合并回来?

谢谢!

最佳答案

为了完整起见,以下是您如何在 data.table 中执行此操作:

library(data.table)

setDT(df)

dat_sums <- df[,lapply(.SD,sum), by = c("sbj","trial"),.SDcols=c("trg","cmp","dis")]

dat_props <- df[,lapply(.SD,function(x){sum(x)/length(x)}), by=c("sbj","trial"), .SDcols=c("trg","cmp","dis")]

关于r:除了循环似乎别无选择的情况,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35829707/

相关文章:

php - 将 1 行,1 字段查询直接保存到变量中,而不是使用 while 循环

javascript - 三重条件 do while 循环

r - 如何在 R 中使用带有 sf/rnaturalearth/ggplot 的 Mollweide 投影旋转世界地图?

r - 使用 %>% 动态指定因子水平

regex - 在 R 中使用 Regex 获取 Twitter @Username

python - 如何以前面规定的不同方式读取大块的行,触发 Python 中的文本

javascript - 作为本练习的解决方案,这两个循环之间的主要区别是什么? (学习javascript)

r - 使用 Roxygen 在同一个文件中记录两个 S3 方法

html - 在什么时候使用处理函数可以提高 HTML 解析效率?

java - 在java中暂停for循环