【问题标题】:Creating averaged time-bins from an existing dataframe从现有数据帧创建平均时间段
【发布时间】:2014-03-20 17:33:09
【问题描述】:

我有以下名为“EasyScaled”的数据框;

str(EasyScaled)
'data.frame':   675045 obs. of  3 variables:
$ Trial           : chr  "1_easy.wav" "1_easy.wav" "1_easy.wav" "1_easy.wav" ...
$ TrialTime       : num  3000 3001 3002 3003 3004 ...
$ PupilBaseCorrect: num  0.784 0.781 0.78 0.778 0.777 ...

“TrialTime”数字变量表示每个数据点的时间(3000 = 3000ms、3001 = 3001 ms 等),“PupilBaseCorrect”是我的因变量,“Trial”变量指的是实验性试验。

我想创建一个新对象,首先将我的数据分为 3 个时间段(TimeBin1 = 3000-8000ms,TimeBin2 = 8001-13000ms,TimeBin3 = 13001 - 18000ms),然后计算每个时间段的平均值(每次试验),这样我最终会得到这样的东西(给出的值反映了“PupilBaseCorrect”);

 Trial        TimeBin1     TimeBin2     TimeBin3
 1_easy       0.784        0.876        0.767 
 34_easy      0.781        0.872        0.765
 35_easy      0.78         0.871        0.762 
 ...etc       ...etc       ...etc       ....etc

我曾尝试使用 cut()、ddply() 以及此博客 http://lamages.blogspot.co.uk/2012/01/say-it-in-r-with-by-apply-and-friends.html 上的一些建议,但未能找到正确的代码。我也试过这个;

EasyTimeBin <- aggregate(PupilBaseCorrect ~ Trial + TrialTime[3000:8000, 8001:1300,1301:1800], data=EasyScaled, mean)

但出现以下错误;

Error in TrialTime[3000:8000, 8001:1300, 1301:1800] : 
incorrect number of dimensions

任何建议或意见将不胜感激。

【问题讨论】:

  • 您想要TrailTime[which(TrailTime %in% c(3000:8000,8001:1300,1301:1800))],或者利用aggregate 中的subset 参数
  • 谢谢理查德,如果罗伯特下面的方法证明很棘手,我会试一试。

标签: r dataframe average


【解决方案1】:

正确使用 cut 和 ddply 是正确的,但这里有一些香草 R 鸡肉刮擦可以满足您的需求。

# Generate example data
EasyScaled <- data.frame(
  Trial = paste0(c(sapply(1:3, function(x) rep(x, 9))), "_easy.wav"),
  TrialTime = c(sapply(seq_len(9)-1, function(x) (floor(x/3))*5000 + x%%3 + 3000)),
  PupilBaseCorrect = rnorm(27, 0.78, 0.1)
)

# group means of PupilBaseCorrect by Trial + filename
tmp <- tapply(EasyScaled$PupilBaseCorrect,
    paste0(EasyScaled$Trial, ',',
           as.integer((EasyScaled$TrialTime - 3000)/5000)+1), mean)

# melt & recast the array manually into a dataframe
EasyTimeBin <- do.call(data.frame,
   append(list(row.names = NULL,
               Trial = gsub('.wav,.*','',names(tmp)[3*seq_len(length(tmp)/3)])), 
     structure(lapply(seq_len(3),
         function(x) tmp[3*(seq_len(length(tmp)/3)-1) + x]
       ), .Names = paste0("TimeBin", seq_len(3))
     )
   )
)

print(EasyTimeBin)
#  Trial   TimeBin1  TimeBin2  TimeBin3
# 1 1_easy 0.7471973 0.7850524 0.8939581
# 2 2_easy 0.8096973 0.8390587 0.7757359
# 3 3_easy 0.8151430 0.7855042 0.8081268

【讨论】:

  • 非常感谢您的代码 Robert,这非常有帮助(如果可以的话,我会投票)。不过我只有一个问题。使用我自己的数据运行此代码后,我得到了一个包含 60 行的数据框。但是,应该只有 46 个,因为只有 46 个试验。我注意到有些试验是重复的(例如 11_easy),并且每次重复都有不同的值。根据您的代码,我无法弄清楚为什么会发生这种情况。你有什么想法吗?
  • 为了扩展我之前的评论,它在数据框中看起来每三次试验都是重复的,所以你会得到这样的行模式:试验 1、试验 2、试验 3、试验 3、试验4,试验 5,试验 6,试验 6,等等......这就是为什么有 60 行而不是 45 行(之前更正;应该有 45 试验,而不是 46)。
  • 如果没有原始数据集则不确定。一个简单的黑客将是dataframe &lt;- dataframe[sapply(unique(dataframe$Trial), function(x) which(x == dataframe$Trial)[1]),]
  • 谢谢罗伯特。不幸的是,我在数据帧中得到的平均值与我在原始“EasyScaled”数据帧上执行算术时计算出的平均值不匹配,使用; 'mean(EasyScaled$PupilBaseCorrect[1:5000])' 等。我对代码的理解不够详细,无法确定可能出错的地方 - 我尝试从#group mean 部分删除“+1”但一直遇到同样的问题。
  • 新数据框中的错误具有以下模式:新数据框中的第一行是正确的(“1_easy”试验),但对于下一行,值似乎向右移动,所以'timebin1' 的正确值实际上在 'timebin2' 之下,而在下一行中,'timebin2' 的正确值实际上在 timebin3' 之下等等。这可能会被认为是基本的,但如果我真的很感激的话您可以标记您提供的每一行代码,以便我可以尝试找出如何适当地调整它。感谢您一直以来的帮助。
猜你喜欢
  • 2023-01-12
  • 2021-11-02
  • 1970-01-01
  • 2017-10-13
  • 2017-12-15
  • 1970-01-01
  • 2017-08-31
  • 1970-01-01
  • 2021-12-22
相关资源
最近更新 更多