我正在尝试在大型数据框中编制索引。 sdata框架有300万个观测值和26个变量(在底部)。
setsize <- 6
eccent <- 150
ctrX <- 400
ctrY <- 300
xyrotate <- function(x,y,ctrX,ctrY,angle){
distX <- x - ctrX;
distY <- y - ctrY;
radians <- angle * (pi/180);
rotX <- ctrX + (distX*cos(radians)) - (distY*sin(radians));
rotY <- ctrY + (distX*sin(radians)) + (distY*cos(radians));
coordinates <- list("X" = rotX,"Y" = rotY)
return(coordinates)
}
loc <- data.frame(x = numeric(setsize),
y = numeric(setsize))
loc$x[1] <- ctrX
loc$y[1] <- ctrY - eccent
for(i in 2:setsize){
coord <- xyrotate(loc$x[1], loc$y[1],ctrX,ctrY,(i-1)*(360/setsize))
loc$x[i] <- coord$X
loc$y[i] <- coord$Y
}
gazedist <- matrix(nrow=nrow(sdata), ncol = setsize)
for(d in 1:setsize){
x <- sdata$RIGHT_GAZE_X-loc$x[d]
y <- sdata$RIGHT_GAZE_Y-loc$y[d]
gazedist[,d] <- sqrt(x^2+y^2)
}
sdata$gdist_T <- 0
sdata$gdist_T <- gazedist[ ,sdata$t_targLoc]
此处的最后一行导致R崩溃。有没有办法将sdata $ t_targLoc [i]的值插入到gazedistance [i,d]的d值中。 for循环等价物是:
for(i in 1:length(gazedist)){
sdata$gdist_T[i] <- gazedist[i,sdata$t_targLoc[i]]
}
但是在R ......中这会很慢......
sdata结构
structure(list(RIGHT_GAZE_X = c(409.5, 409.6, 409.5, 409.4, 409.3,
409.2, 409.1, 409, 408.9, 408.8), RIGHT_GAZE_Y = c(291.9, 291.5,
290.9, 290.3, 290.3, 290.3, 289.8, 289.2, 288.7, 288.8), RECORDING_SESSION_LABEL = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "ET101", class = "factor"),
t_block = c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), t_trialNum = c(129L,
129L, 129L, 129L, 129L, 129L, 129L, 129L, 129L, 129L), t_subjNum = c(101L,
101L, 101L, 101L, 101L, 101L, 101L, 101L, 101L, 101L), t_colCond = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "green", class = "factor"),
t_targLoc = c(3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), t_targID = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "L", class = "factor"),
t_targShape = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L), .Label = "diamond", class = "factor"), t_singLoc = c(5L,
5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L), t_singPres = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "P", class = "factor"),
t_singDist = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), t_singAngle = c(120L,
120L, 120L, 120L, 120L, 120L, 120L, 120L, 120L, 120L), t_targAngle = c(120L,
120L, 120L, 120L, 120L, 120L, 120L, 120L, 120L, 120L), t_RESP = structure(c(1L,
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = "L", class = "factor"),
t_ACC = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), t_RT = c(686.1062,
686.1062, 686.1062, 686.1062, 686.1062, 686.1062, 686.1062,
686.1062, 686.1062, 686.1062), TRIAL_START_TIME = c(1031031L,
1031031L, 1031031L, 1031031L, 1031031L, 1031031L, 1031031L,
1031031L, 1031031L, 1031031L), TIMESTAMP = c(1031030, 1031032,
1031034, 1031036, 1031038, 1031040, 1031042, 1031044, 1031046,
1031048), IP_START_TIME = c(1031031L, 1031031L, 1031031L,
1031031L, 1031031L, 1031031L, 1031031L, 1031031L, 1031031L,
1031031L), currtime = c(0, 2, 4, 6, 8, 10, 12, 14, 16, 18
), currsamp = c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), gdist_T = c(0,
0, 0, 0, 0, 0, 0, 0, 0, 0), gdist_S = c(0, 0, 0, 0, 0, 0,
0, 0, 0, 0), gdist_NS = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), .Names = c("RIGHT_GAZE_X",
"RIGHT_GAZE_Y", "RECORDING_SESSION_LABEL", "t_block", "t_trialNum",
"t_subjNum", "t_colCond", "t_targLoc", "t_targID", "t_targShape",
"t_singLoc", "t_singPres", "t_singDist", "t_singAngle", "t_targAngle",
"t_RESP", "t_ACC", "t_RT", "TRIAL_START_TIME", "TIMESTAMP", "IP_START_TIME",
"currtime", "currsamp", "gdist_T", "gdist_S", "gdist_NS"), row.names = 53170:53179, class = "data.frame")
答案 0 :(得分:2)
您似乎想要抓住sdist$$t_targLoc[i]
的第i行和gazedist
列。有一个内置的。使用:
sdata$gdist_T <- gazedist[cbind(1:nrow(gazedist),sdata$t_targLoc)]
以下是一个例子:
m <- matrix(1:25,nc=5)
m
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 6 11 16 21
# [2,] 2 7 12 17 22
# [3,] 3 8 13 18 23
# [4,] 4 9 14 19 24
# [5,] 5 10 15 20 25
v <- c(1,3,5,2,4)
m[cbind(1:5,v)]
# [1] 1 12 23 9 20
BTW,您的第一个for
循环可以替换为:
loc <- as.data.frame(xyrotate(ctrX,ctrY-eccent, ctrX,ctrY,(1:(setsize-1))*360/setsize))
loc <- rbind(c(X=ctrX,Y=ctrY-eccent),lloc)
您的第二个for
循环可以替换为,例如,
f <- function(x,y) {
x <- sdata$RIGHT_GAZE_X-x
y <- sdata$RIGHT_GAZE_Y-y
sqrt(x^2+y^2)
}
ggazedist <- mapply(f, loc$x, loc$y)
identical(gazedist,ggazedist)
# [1] TRUE
答案 1 :(得分:1)
1:nrow(sdat)
,列索引为sdata$t_targLoc
。这不是内置的(我知道),但我们可以将矩阵转换为矢量并获取正确的值。
gazedist_vals = as.vector(gazedist)
rows = 1:nrow(sdat)
cols = sdat$t_targLoc
indices = (cols - 1) * nrow(gazedist) + rows
sdata$gdist_T = gazedist_vals[indices]
我认为这会做你想要的。
您的数据摘录并未说明这一点,因为t_targLoc
始终是3.这里有一点说明:
x = matrix(c(5,2,65,8,4,2), nrow = 2)
x
# [,1] [,2] [,3]
# [1,] 5 65 4
# [2,] 2 8 2
as.vector(x)
# [1] 5 2 65 8 4 2
rows = c(1, 1, 2)
cols = c(3,2,1)
inds = (cols - 1) * nrow(x) + rows
as.vector(x)[inds]
# [1] 4 65 2
一条评论:您的问题是彻底的,但 minimal 示例通常更可取。你给了我们26列数据,其中只有一列是必需的。你给了我们函数和代码来计算距离,当你刚刚给出一个距离矩阵(然后只需要一个数据列)。像我的x
矩阵以及rows
和cols
向量这样的小例子可能就是您展示问题所需的全部内容。
答案 2 :(得分:0)
你可以,但我怀疑你会节省很多时间,除非你找到一种完全矢量化的方法。换句话说,你必须避免使用像apply或sapply这样的函数,这些函数都基于C中的for循环,因此,如果有的话,循环的速度不会比正常快。
someFunction <- function(x) ifelse(x %in% seq(0, 50000, 100), 1, 0)
# Here you have "vectorized" the indexing
system.time(sapply(1:nrow(diamonds), someFunction))
# 2.6 elapsed secs
## vs here where you're just using a for loop
system.time(
for(i in 1:nrow(diamonds)) {
k[i] <- someFunction(i)
}
)
# 2.7 elapsed secs