我是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(反应时间)。每个主题都会看到多个项目。
我希望计算异常值然后将它们标准化(尽管我不会真的担心这个问题中的解决方案)。作为第一步,我使用一些简单的函数来计算每个主题的每个区域的平均值和标准差,折叠项目(即(主题在该区域中的所有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
...
问题在于我现在需要将所有方法与每个主题的正确区域相关联。也就是说,我想生成看起来像这样的输出(请注意,所有Subject 102 Region 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不会完成将一个值扩展和匹配到另一个值的工作。也许我需要使用融化或某些使用密钥的功能?
我希望有人能指出我的相关功能让我阅读,以便我可以自己尝试,或只是帮助一些代码。
感谢阅读...
答案 0 :(得分:3)
您可以使用ddply
包中的plyr
函数完成此任务。使用ddply
和ave
功能:
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
聚合的均值和sd都会被放入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)))
答案 1 :(得分: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
它按地区,主题然后项目
排序答案 2 :(得分:2)
99%的人完成了你的工作。你唯一需要做的就是&#34;漂亮的&#34;您的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)
答案 3 :(得分: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]
}
}