3

我是 R 和这个列表的新手。我希望接下来的问题不是太基本或不了解情况。过去几个小时我一直在查看档案,但无济于事,所以我在这里发布。部分问题是我并不完全知道在引用我需要的功能时要使用的正确术语,这会使搜索变得困难。话虽如此,这就是我需要解决的问题:

我有一个如下所示的数据框:

   Subject Item Region   RT  
13     102    1  R1 1245  
14     102    4  R1 1677  
15     102    7  R1 1730  
25     103    1  R1  815  
26     103    4  R1  828  
27     103    7  R1  985  
1489     102    1  R2 356  
1490     102    4  R2 510  
1491     102    7  R2 544  
1501     103    1  R2 447  
1502     103    4  R2 486  
1503     103    7  R2 221  
...  

每个受试者对一个项目的多个区域都有一个 RT(反应时间)。每个主题看到多个项目。

我希望计算异常值,然后对它们进行规范化(尽管我真的不会担心这个线程中的解决方案)。作为第一步,我使用了一些简单的函数来计算每个主题的每个区域的平均值和 SD,并跨项目折叠(即(该主题在该区域中所有 RT 的平均值):

Mean = with(test, aggregate(RT, by = list(Subject,Region),mean, na.rm=TRUE))  
SD = with(test, aggregate(RT, by = list(Subject,Region),sd, na.rm=TRUE))  

然后我使用 cbind 并进行了一些重命名以将数据全部放在一个数据框中:

Subject Region      Mean         SD  
1       102  R1 1143.7778  202.25530  
2       102  R2  431.8611  125.84393  
9       103  R1  923.0833  179.51098  
10      103  R2  344.1667  146.51192  
...  

问题是我现在需要将所有方法与每个主题的正确区域相关联。也就是说,我想生成如下所示的输出(请注意,所有主题 102 区域 R1 具有相同的均值和 SD,但不同的 RT 等):

Subject Item Region   RT Mean         SD  
13     102    1  R1 1245 1143.7778  202.25530  
14     102    4  R1 1677 1143.7778  202.25530  
15     102    7  R1 1730 1143.7778  202.25530  
25     103    1  R1  815 923.0833  179.51098  
26     103    4  R1  828 923.0833  179.51098  
27     103    7  R1  985 923.0833  179.51098  
1489     102    1  R2 356 431.8611  125.84393   
1490     102    4  R2 510 431.8611  125.84393  
1491     102    7  R2 544 431.8611  125.84393  
1501     103    1  R2 447 344.1667  146.51192  
1502     103    4  R2 486 344.1667  146.51192  
1503     103    7  R2 221 344.1667  146.51192  

似乎 merge 和 cbind 不会完成将一个值扩展和匹配到另一个值的工作。也许我需要使用融化或一些使用键的功能?

我希望有人可以向我指出相关功能供我阅读,以便我可以自己尝试,或者只是帮助一些代码。

谢谢阅读...

4

4 回答 4

3

ddply您可以使用包中的函数完成此任务plyr。使用ddplyave作用:

test <- read.table(text="
Subject Item Region   RT  
13     102    1  R1 1245  
14     102    4  R1 1677  
15     102    7  R1 1730  
25     103    1  R1  815  
26     103    4  R1  828  
27     103    7  R1  985  
1489     102    1  R2 356  
1490     102    4  R2 510  
1491     102    7  R2 544  
1501     103    1  R2 447  
1502     103    4  R2 486  
1503     103    7  R2 221", header=T)

library(plyr)
ddply(test, .(Subject, Region), transform, Mean=ave(RT), SD=ave(RT, FUN=sd))
   Subject Item Region   RT      Mean        SD
1      102    1     R1 1245 1550.6667 266.03822
2      102    4     R1 1677 1550.6667 266.03822
3      102    7     R1 1730 1550.6667 266.03822
4      102    1     R2  356  470.0000 100.17984
5      102    4     R2  510  470.0000 100.17984
6      102    7     R2  544  470.0000 100.17984
7      103    1     R1  815  876.0000  94.62029
8      103    4     R1  828  876.0000  94.62029
9      103    7     R1  985  876.0000  94.62029
10     103    1     R2  447  384.6667 143.07457
11     103    4     R2  486  384.6667 143.07457
12     103    7     R2  221  384.6667 143.07457

您可以aggregate像以前一样使用函数检查结果。

> with(test, aggregate(RT, by = list(Subject,Region),mean, na.rm=TRUE))  
  Group.1 Group.2         x
1     102      R1 1550.6667
2     103      R1  876.0000
3     102      R2  470.0000
4     103      R2  384.6667
> with(test, aggregate(RT, by = list(Subject,Region),sd, na.rm=TRUE))
  Group.1 Group.2         x
1     102      R1 266.03822
2     103      R1  94.62029
3     102      R2 100.17984
4     103      R2 143.07457

如您所见,均值和标准差都由Subject和聚合Region到您的data.frame( test) 中。

编辑

如果要处理NA,您可能需要使用以下编辑后的代码:

ddply(test, .(Subject, Region), transform, 
      Mean=ave(RT, FUN = function(x) mean(x, na.rm=TRUE)),
      SD=ave(RT, FUN=function(x) sd(x, na.rm=TRUE)))
于 2012-08-16T14:17:00.457 回答
3

这可以使用sqldf

df1<-read.table(header=T,text="Subject Item Region   RT  
13     102    1  R1 1245  
14     102    4  R1 1677  
15     102    7  R1 1730  
25     103    1  R1  815  
26     103    4  R1  828  
27     103    7  R1  985  
1489     102    1  R2 356  
1490     102    4  R2 510  
1491     102    7  R2 544  
1501     103    1  R2 447  
1502     103    4  R2 486  
1503     103    7  R2 221")

df2<-read.table(header=T,text="Subject Region      Mean         SD  
1       102  R1 1143.7778  202.25530  
2       102  R2  431.8611  125.84393  
9       103  R1  923.0833  179.51098  
10      103  R2  344.1667  146.51192")  

library(sqldf)
sqldf("SELECT df1.*,df2.Mean,df2.SD from df1,df2
        WHERE df1.Region=df2.Region 
         GROUP BY df1.Region,df1.Subject,df1.Item")

#   Subject Item Region   RT      Mean       SD
#1      102    1     R1 1245 1143.7778 202.2553
#2      102    4     R1 1677 1143.7778 202.2553
#3      102    7     R1 1730 1143.7778 202.2553
#4      103    1     R1  815 1143.7778 202.2553
#5      103    4     R1  828 1143.7778 202.2553
#6      103    7     R1  985 1143.7778 202.2553
#7      102    1     R2  356  431.8611 125.8439
#8      102    4     R2  510  431.8611 125.8439
#9      102    7     R2  544  431.8611 125.8439
#10     103    1     R2  447  431.8611 125.8439
#11     103    4     R2  486  431.8611 125.8439
#12     103    7     R2  221  431.8611 125.8439

它按地区、主题然后项目排序

于 2012-08-17T02:31:41.250 回答
2

你已经完成了 99% 的工作。您唯一需要做的就是“美化”您的aggregate()输出,以便它更礼貌地与merge(). 请注意,在下文中,您将指定输出列名称,以便它们可以轻松合并。

然后,我们使用Reduce()递归合并。

Mean = with(test, aggregate(list(mean = RT), 
                            by = list(Subject = Subject, Region = Region), 
                            mean, na.rm=TRUE))
SD = with(test, aggregate(list(sd = RT), 
                          by = list(Subject = Subject, Region = Region), 
                          sd, na.rm=TRUE))
Reduce(function(x, y) merge(x, y), list(test, Mean, SD))
#    Subject Region Item   RT      mean        sd
# 1      102     R1    1 1245 1550.6667 266.03822
# 2      102     R1    4 1677 1550.6667 266.03822
# 3      102     R1    7 1730 1550.6667 266.03822
# 4      102     R2    1  356  470.0000 100.17984
# 5      102     R2    4  510  470.0000 100.17984
# 6      102     R2    7  544  470.0000 100.17984
# 7      103     R1    1  815  876.0000  94.62029
# 8      103     R1    4  828  876.0000  94.62029
# 9      103     R1    7  985  876.0000  94.62029
# 10     103     R2    1  447  384.6667 143.07457
# 11     103     R2    4  486  384.6667 143.07457
# 12     103     R2    7  221  384.6667 143.07457
# merge(merge(test, Mean), SD)
于 2012-08-16T16:49:06.223 回答
1

这是一种蛮力,但它有效

test <- data.frame(Subject=rep(c(102,103),2,each=3), Item=rep(c(1,4,7),4),Region=rep(c("R1","R2"),each=6), RT= c(1245,1677,1730,815,828,985,356,510,544,447,486,221))

Mean = with(test, aggregate(RT, by = list(Subject,Region),mean, na.rm=TRUE))  
SD = with(test, aggregate(RT, by = list(Subject,Region),sd, na.rm=TRUE))  

aa <- data.frame(test, Mean=0, SD=0)

for (i in 1:nrow(aa)) {
  for(j in 1:nrow(Mean)){
    if (aa$Subject[i]==Mean$Group.1[j] & aa$Region[i]==Mean$Group.2[j]) aa$Mean[i] <- Mean$x[j]
    if (aa$Subject[i]==SD$Group.1[j] & aa$Region[i]==SD$Group.2[j]) aa$SD[i] <- SD$x[j]
  }
}
于 2012-08-16T14:18:43.493 回答