提问人:alyb_batgirl 提问时间:3/16/2023 更新时间:3/16/2023 访问量:19
跨多个子列表的循环计算
Loop Calculation Across Multiple Sublists
问:
我有一组在竞技场中移动的小鼠的坐标数据,每个试验都有自己的数据框。对于每个文件,我想计算鼠标在给定时间点(帧)与设置对象(在本例中为气味点)的距离。气味点的位置随着每次试验而变化。由于管道中其他分析的性质,此时我在列表中提供了所需值的数据帧。
下面是示例数据,使用随机假数据来显示我正在使用的列表的结构。
#These data frames mimic the structure of the coordinate data (main variables of interest are frame, x, y)
df1 <- data.frame(frame = seq(1:50),
x = runif(50, min=1, max=90),
y = runif(50, min=1, max=90))
df2 <- data.frame(frame = seq(1:50),
x = runif(50, min=1, max=90),
y = runif(50, min=1, max=90))
#These data frames mimic the structure of the coordinates of the non-moving locations (i.e. odorspot, arena corners. While the only location I'm interested in is the odorspot ("os"), I'm showing this with other coordinate locations because that is how the data is structured after my other processing steps)
med1 <- data.frame(pointname = c("tl", "tr", "bl", "br", "os", "cs"),
x = runif(6, min=1, max=90),
y = runif(6, min=1, max=90))
med2 <- data.frame(pointname = c("tl", "tr", "bl", "br", "os", "cs"),
x = runif(6, min=1, max=90),
y = runif(6, min=1, max=90))
datalist <- list(data1 = df1,
data2 = df2)
medlist <- list(data1 = med1,
data2 = med2)
#Example of the list structure
biglist <- list(data = datalist,
median.data = medlist)
因此,对于每个“数据”数据帧,我想添加一个名为 DistSpot 的新列,即计算鼠标在每一帧中与气味点的距离。
最终数据应如下所示:
frame x y SpotDist
1 0 41.18153 84.49540 66.88208
2 1 41.18153 84.51059 66.89718
3 2 41.18153 84.54423 66.93062
4 3 41.03425 84.64317 67.01337
5 4 40.96008 84.93739 67.29827
6 5 40.70080 85.17731 67.51068
对于 biglist$data$data1,相应的气味点坐标将在 biglist$median.data$data1[5,2](第五行,第二列)中找到
我试图编写一个循环函数来进行计算,但它没有运行(在闭包类型上给出错误)。我也不确定我是否正确调用了 median.data 变量。
DistanceOdor <- function(x){
for (i in 1:length(x$data)){
x$data[i]$diffx <- (x$data[i]$x - x$median.data[5,2])^2
x$data[i]$diffy <- (x$data[i]$y - x$median.data[5,3])^2
x$data[i]$distspot <- sqrt(x$data[i]$diffx + x$data[i]$diffy)
}
return(x)
}
提前致谢!
答:
2赞
MrFlick
3/16/2023
#1
使用基数 R,您可以对不同的输入进行计算,然后用 计算欧几里得距离。例如Map
transform
Map(function(pos, ref) {
os <- subset(ref, pointname=="os")
transform(pos, SpotDist = sqrt((x-os$x)^2 + (y-os$y)^2))
}, biglist$data, biglist$median.data)
# $data1
# frame x y SpotDist
# 1 1 54.588150 60.336306 50.926487
# 2 2 18.358910 64.556675 31.570075
# 3 3 87.014827 69.396838 83.830691
# 4 4 58.930592 84.829107 69.916124
# ...
# $data2
# frame x y SpotDist
# 1 1 68.006640 27.077371 77.26383
# 2 2 76.747999 68.794598 75.35945
# 3 3 76.288808 58.011732 75.31435
# 4 4 9.879642 81.893493 17.74808
# ...
这些是我在您提供的代码之前运行时获得的值。set.seed(15)
如果你想使用你的函数,你需要更加小心 vs .使用前者对列表进行子集,使用后者从列表中提取项。你可以做到[]
[[]]
DistanceOdor <- function(x){
for (i in 1:length(x$data)){
x$data[[i]]$diffx <- (x$data[[i]]$x - x$median.data[[i]][5,2])^2
x$data[[i]]$diffy <- (x$data[[i]]$y - x$median.data[[i]][5,3])^2
x$data[[i]]$distspot <- sqrt(x$data[[i]]$diffx + x$data[[i]]$diffy)
}
return(x)
}
评论
0赞
alyb_batgirl
3/16/2023
谢谢,这太完美了!并感谢您带括号的注释。我最初将它们放在双括号中,但我仍然收到错误。一定在某处有另一个错别字,因为复制你的代码是有效的。
0赞
MrFlick
3/16/2023
您还缺少值上的双括号索引。x$median.data
评论