我正在和一台机器一起工作,它能把微小的粒子扔进含有96个细胞(8x12栅格)的细胞中。有时细胞间会发生交叉污染,因为要给一个细胞的粒子落入相邻的细胞中。机器完成后,我们测量每个单元的重量。我想要一个脚本,将这些权重信息与细胞网格的空间信息结合起来,以识别潜在的交叉污染案例。我正努力想出最符合逻辑的方法来做这件事,任何反馈都将是非常感谢的。
理想情况下,脚本将在R中实现(如果可能的话,可以使用dplyr,尽管我不确定它是否与这类任务相关)。
输入数据如下(对于前4行网格):
Cell Weight
A1 2
B1 2
C1 2
D1 2
E1 2
F1 2
G1 2
H1 2
A2 2
B2 0.1
C2 2
D2 4
E2 2
F2 0.1
G2 2
H2 2
A3 2
B3 2
C3 2
D3 2
E3 2
F3 4
G3 2
H3 2
A4 2
B4 2
C4 6
D4 2
E4 2
F4 2
G4 2
H4 2A1-H1是单元格的第一行,A2-H2是第二行,一直到A12-H12。
因此,实际上它在细胞网格中的外观如下所示,每个细胞的重量都是测量出来的:
2 2 2 2 2 2 2 2
2 0.1 2 4 2 0.1 2 2
2 2 2 2 2 4 2 2
2 2 6 2 2 2 2 2对于上述情况,我想强调的是,细胞F3可能含有来自于细胞F2的颗粒的污染,因为细胞F3的中位重量是其他细胞的两倍,并且直接位于细胞F2的下方,这几乎是空的,这意味着原本用于细胞F2的粒子可能已经掉进了附近的细胞F3中。
我不怀疑C4或D2细胞,因为尽管它们比预期的重,但我知道粒子不可能从它们想要的细胞降到很远的地方,所以如果与感兴趣的细胞直接相邻的细胞没有异常地耗尽重量,那么我就不会怀疑污染。
我认为一个棘手的部分是确定一个细胞的重量是否比预期的少或更多,因为由于重量测量中的噪音,细胞间的重量有相当大的差异。我可以做一个直截了当的解决方案,比如考虑任何重量<1的单元格都是空的。然而,我认为更好的解决办法是计算所有细胞的中位重量,然后将体重低于中位数10%的细胞视为空细胞。污染检查只需要对比中位重量大1.5倍的细胞进行。对于如何处理这一问题,我非常乐意听取建议。
理想情况下,输出将是添加到表中的一个额外行。没有可疑污染的细胞会让这一行空着。而任何怀疑含有污染的单元格都包含该单元格/s的名称,而该单元/s的污染可能来自这一行。
因此,对于这个例子:
Cell Weight Contamination
A1 2
B1 2
C1 2
D1 2
E1 2
F1 2
G1 2
H1 2
A2 2
B2 0.1
C2 2
D2 4
E2 2
F2 0.1
G2 2
H2 2
A3 2
B3 2
C3 2
D3 2
E3 2
F3 4 F2
G3 2
H3 2
A4 2
B4 2
C4 6
D4 2
E4 2
F4 2
G4 2
H4 2 任何帮助的想法,以解决这个污染检查问题的最佳方法,将不胜感激。我也不确定是否有一种有效的方法将数据列转换为R中有用的矩阵,以便为每个单元格清楚地检查每个单元格的上下和左、右(忽略边缘上的单元格丢失的单元格)。目前,数据是线性的,但是我假设它必须转换成一个矩阵,这样这个测试才能按预期工作。
很抱歉,如果这个问题的结构很差,我已经试着尽可能清楚地回答。我很乐意接受任何建议,使它更清楚。
提前谢谢。
发布于 2017-11-09 23:11:48
您可以这样做,而不需要重塑您的数据。假设您的数据被称为my.data:
library(data.table)
DT <- as.data.table(my.data)
median.weight <- DT[, median(Weight)]
DT[,
Contamination := ifelse(
Weight >= median.weight * 1.5 &
((.I %% 8 != 0 & shift(Weight, n=1, type="lead") < 1) | #not in last column, check next value
(.I %% 8 != 1 & shift(Weight, n=1, type="lag") < 1) | #not in first column, check previous value
(.I<88 & shift(Weight, n=8, type="lead") < 1) |
(.I>8 & shift(Weight, n=8, type="lag") < 1)),
TRUE,
FALSE
)
]这将将Contamination列设置为TRUE,如果该行的Weight为1.5*,且相邻的任何单元格的权重都低于1。shift函数用于将数据引导/滞后1或8行,以利用具有*8网格的事实。.I将当前行号存储在data.table中。
编辑:使用模块化操作符%%来检查网格的第一列还是最后一列。
发布于 2017-11-09 23:35:05
在依赖一个显式嵌套循环的同时,将一些天真的东西组合在一起,允许来自3-8个相邻细胞中的任何一个细胞的污染(如果是在一个角落,则是三个,如果是在中间的话,则是8个)。它还允许可能来自多个相邻细胞的污染。尽管如此,我确信有一种更像R的方法,其规模要比这大得多。
weight <- c(2, 2, 2, 2, 2, 2, 2, 2, 2, 0.1, 2, 4, 2, 0.1, 2, 2,
2, 2, 2, 2, 2, 4, 2, 2, 2, 2, 6, 2, 2, 2, 2, 2)
# for now hardcode number of rows, but if you wanted, you could take
# the maximum numeric portion of the Cell vector
m <- matrix(weight, nrow = 4, byrow = T)
b <- quantile(as.vector(t(m)), c(0.05, 0.95))
# flag cells below/above the 5th/95th percentile, respectively
m1 <- ifelse(m <= b[1], -1, ifelse(m >= b[2], 1, 0))
m2 <- matrix(NA_character_, nrow = nrow(m1), ncol = ncol(m1))
for (i in 1:nrow(m1)) {
for (j in 1:ncol(m1)) {
if (m1[i, j] == 1) {
# don't attempt to go out of matrix bounds
rows <- max(c(i - 1, 1)):min(c(i + 1, nrow(m1)))
cols <- max(c(j - 1, 1)):min(c(j + 1, ncol(m1)))
# allow for multiple possible contamination cells
o <- c()
for (r in rows) {
for (c in cols) {
if (m1[r, c] == -1) {
o <- c(o, paste0(LETTERS[c], r))
}
}
}
if (length(o) > 0) {
m2[i, j] <- paste0(o, collapse = ";")
}
}
}
}
colnames(m2) <- LETTERS[1:ncol(m2)]
rownames(m2) <- 1:nrow(m2)
data.frame(weight, Contaminates = as.vector(t(m2)))另外,如果单元格低于/高于第5/95百分位数,则此标记标记。这个可以根据你的需要改变。
https://stackoverflow.com/questions/47212900
复制相似问题