R 如果值在范围内,则合并2个数据帧
我已经为此挣扎了一段时间,但找不到任何方法,所以如果你能帮助我,我将不胜感激!我是一个编程新手,我的代码可能效率很低,但这是我能想到的最好的 基本上,我有2个.csv文件(fixes.csv和zones.csv),它们包含不同的变量,并且具有不同的行数和列数。第一个文件fixes.csv包含实验期间记录的眼动数据,如下所示:R 如果值在范围内,则合并2个数据帧,r,csv,R,Csv,我已经为此挣扎了一段时间,但找不到任何方法,所以如果你能帮助我,我将不胜感激!我是一个编程新手,我的代码可能效率很低,但这是我能想到的最好的 基本上,我有2个.csv文件(fixes.csv和zones.csv),它们包含不同的变量,并且具有不同的行数和列数。第一个文件fixes.csv包含实验期间记录的眼动数据,如下所示: Order Participant Sentence Fixation StartPosition 1 1 1 1
Order Participant Sentence Fixation StartPosition
1 1 1 1 -6.89
2 1 1 2 -5.88
3 1 1 3 -5.33
4 1 1 4 -4.09
5 1 1 5 -5.36
Sentence Zone ZoneStart ZoneEnd
1 1 -8.86 -7.49
1 2 -7.49 -5.89
1 3 -5.88 -4.51
1 4 -4.51 -2.90
Order Participant Sentence Fixation StartPosition Zone
1 1 1 1 -6.89 2
2 1 1 2 -5.88 2
3 1 1 3 -5.33 3
4 1 1 4 -4.09 3
5 1 1 5 -5.36 3
这包含阅读句子时的眼动记录。所发生的是,20名参与者中的每一位都会阅读一组40个12字的句子,对每个句子中的不同单词进行几个固定,有时还会回头看以前读过的单词。StartPosition列包含屏幕上开始固定的位置(以视角度为单位)。值通常介于-8度和8度之间
第二个文件zones.csv包含有关句子的信息。40个句子中的每个句子包含12个单词,每个单词构成一个兴趣区。zones.csv看起来像这样:
Order Participant Sentence Fixation StartPosition
1 1 1 1 -6.89
2 1 1 2 -5.88
3 1 1 3 -5.33
4 1 1 4 -4.09
5 1 1 5 -5.36
Sentence Zone ZoneStart ZoneEnd
1 1 -8.86 -7.49
1 2 -7.49 -5.89
1 3 -5.88 -4.51
1 4 -4.51 -2.90
Order Participant Sentence Fixation StartPosition Zone
1 1 1 1 -6.89 2
2 1 1 2 -5.88 2
3 1 1 3 -5.33 3
4 1 1 4 -4.09 3
5 1 1 5 -5.36 3
ZoneStart和ZoneEnd指示屏幕上每个区域的开始和结束坐标(以视角度为单位)。因为每个句子中的单词不同,所以每个区域都有一个宽度
我想做的是同时使用这两个文件,以便将zones.csv中的区域编号分配给fixes.csv中的fixations。例如,如果句子1中的第一个固定起始位置在区域1的范围内,我希望将值1指定给它,以便结束文件看起来像这样:
Order Participant Sentence Fixation StartPosition
1 1 1 1 -6.89
2 1 1 2 -5.88
3 1 1 3 -5.33
4 1 1 4 -4.09
5 1 1 5 -5.36
Sentence Zone ZoneStart ZoneEnd
1 1 -8.86 -7.49
1 2 -7.49 -5.89
1 3 -5.88 -4.51
1 4 -4.51 -2.90
Order Participant Sentence Fixation StartPosition Zone
1 1 1 1 -6.89 2
2 1 1 2 -5.88 2
3 1 1 3 -5.33 3
4 1 1 4 -4.09 3
5 1 1 5 -5.36 3
到目前为止,我所尝试的是使用一个循环来自动化这个过程
zones = read.csv(file.choose(), header = TRUE, sep = ",")
fixes = read.csv(file.choose(), header = TRUE, sep = ",")
fixes$SentNo = as.factor(fixes$SentNo)
zones$Sentence = as.factor(zones$Sentence)
zones$Zone = as.factor(zones$Zone)
nfix = nrow(fixes) ## number of fixations in file fixes.csv
nsent = nlevels(fixes$Sentence) ## number of sentences in data file fixes.csv
nzs = nlevels(zones1$Zone) ## number of zones per sentence from file zones.csv
nsz = nlevels(zones$Sentence) ## number of sentences in data file zones.csv
fixes$Zone = 0
for (i in c(1:nfix)){
for (j in c(1:nzs)){
for (k in c(1:nsent){
for (l in c(1:nsz)){
while(fixes$Sentence[k] == zones$Sentence[l]){
ifelse(fixes$StartPosition[i] > zones$ZoneStart[j]
& fixes$StratPosition[i] < zones1$ZoneEnd[j],
fixes$Zone[i] -> zones1$Zone[j], 0)
return(fixes$Zone)
}
}
}
}
zones=read.csv(file.choose(),header=TRUE,sep=“,”)
fixes=read.csv(file.choose(),header=TRUE,sep=“,”)
fixes$SentNo=as.factor(fixes$SentNo)
区域$句子=as.因子(区域$句子)
zones$Zone=as.factor(zones$Zone)
nfix=nrow(fixes)##fixes.csv文件中的固定数量
nsent=nlevels(fixes$句子)##数据文件fixes.csv中的句子数
nzs=nlevels(zones1$Zone)##文件zones.csv中每个句子的区域数
nsz=nlevels(zones$句子)##数据文件zones.csv中的句子数
修复$Zone=0
对于(c中的i(1:nfix)){
对于(c中的j(1:nzs)){
对于(c中的k(1:nsent){
对于(c(1:nsz)中的l){
while(修复$SECTION[k]==区域$SECTION[l]){
ifelse(修复$StartPosition[i]>zones$ZoneStart[j]
&修复$StratPosition[i]zones1$Zone[j],0)
返回(修复$Zone)
}
}
}
}
但这只是返回大量的零,而不是为每个固定指定一个区域编号。当两个单独的.csv文件具有不同的行数和列数时,是否可以以这种方式使用它们?我尝试按句子合并它们,并从一个大的组合文件中工作,但这没有帮助,因为这似乎会打乱固定顺序ns在一个文件中,区域顺序在另一个文件中
任何帮助都将不胜感激
谢谢!我认为最好的方法是将
区域
更改为更友好的格式,以适应您的工作:
ZoneLookUp = lapply(split(zones, zones$Sentence), function(x) c(x$ZoneStart, x$ZoneEnd[nrow(x)]))
#$`1`
#[1] -8.86 -7.49 -5.88 -4.51 -2.90
然后,您可以轻松查找每个分区:
fixes$Zone = NULL
for(i in 1:nrow(fixes))
fixes$Zone[i] = cut(fixes$StartPosition[i], ZoneLookUp[[fixes$Sentence[i]]], labels=FALSE)
如果性能是一个问题,您可以(仅)使用
by
或data.table
和by.使用sqldf
软件包来采取稍微不那么简单的方法:
library(sqldf)
#dummy data
fixes <- read.table(text="
Order Participant Sentence Fixation StartPosition
1 1 1 1 -6.89
2 1 1 2 -5.88
3 1 1 3 -5.33
4 1 1 4 -4.09
5 1 1 5 -5.36
",header=TRUE)
zones <- read.table(text="
Sentence Zone ZoneStart ZoneEnd
1 1 -8.86 -7.49
1 2 -7.49 -5.89
1 3 -5.88 -4.51
1 4 -4.51 -2.90
",header=TRUE)
#output merged result
res <-
sqldf("SELECT [Order],Participant,f.Sentence,Fixation,StartPosition,Zone
FROM fixes f,zones z
WHERE f.Sentence=z.Sentence AND
f.StartPosition>=z.ZoneStart AND
f.StartPosition<z.ZoneEnd")
库(sqldf)
#虚拟数据
修复Bioconductor中有一个名为IRanges的软件包,可以满足您的需求
首先,为您的区域形成一个IRanges对象:
zone.ranges <- with(zones, IRanges(ZoneStart, ZoneEnd))
编辑:刚刚意识到您有浮点值,而IRanges是基于整数的。因此,考虑到您的精度,您需要将坐标乘以100。对于v1.9.8版(2016年11月25日),数据。table
已获得执行非等联接和范围联接的能力:
资料
修复