我需要在我的大脑成像数据中编辑一些ER标记,这基本上意味着,如果连续的非零条目具有一定的值,我需要更改条目的值。我不知道我是否需要为它编写一个自定义函数(如果我需要这样做的话,请在正确的方向上推动一下)。
在一个示例中更好地说明我的问题(假设col标记是包含有关标记值的信息的16000行数据集的片段):
markers = matrix(c(1,0,0,0,0,2,0,0,0,0,1,0,0,0,3), ncol = 1)我需要将值1改为(f.e.)如果下一个非零项为2(但如果为3),则为9。它们之间没有相等的间距(这意味着,这两个感兴趣的条目之间可能有3-8个零项。
我很乐意提供任何帮助,因为我真的不想手动更改这些值。
发布于 2017-12-14 23:24:53
也许不是最简单的方法,但是这里有一种使用基本R::我将一步一步地编写它的方法,这样您就可以看到在每一步中发生了什么。
先做rle
b <- rle(markers[,1])$values检查哪些元素是1
z <- which(b==1)现在检查0是否是前面的一个元素,如果是,取前面两个元素的索引
k <- ifelse(b[z + 1] == 0, z + 2, z + 1)现在检查这些元素是否等于2,删除任何不是的元素。
v <- ifelse(b[k] == 2, z, NA)
v <- na.omit(v)将剩下的索引值更改为9。
b[v] = 9 把向量拿回来
rep(b, times = rle(markers[,1])$lengths)
#output
[1] 9 0 0 0 0 2 0 0 0 0 1 0 0 0 3
markers[,1]
#output
[1] 1 0 0 0 0 2 0 0 0 0 1 0 0 0 3以下是一个小小的基准:
evers <- function(markers){require(dplyr);
df <- sapply(1:nrow(markers), function(i) lead(markers, i - 1))
idx <- which(df[, 1] == 1);
idx
idx <- idx[sapply(idx, function(i) any(df[i, 2:nrow(df)] == 2, na.rm = TRUE))]}
mss <- function(markers) {
b <- rle(markers[,1])$values
z <- which(b==1)
k <- ifelse(b[z + 1] == 0, z + 2, z + 1)
v <- ifelse(b[k] == 2, z, NA)
v <- na.omit(v)
b[v] = 9
rep(b, times = rle(markers[,1])$lengths)
b
}
microbenchmark(
mss(markers),
evers(markers)
)
#Unit: microseconds
expr min lq mean median uq max neval
mss(markers) 42.667 45.555 118.2324 50.046 52.1315 6681.986 100
evans(markers) 128.322 133.775 271.2453 136.021 140.6725 12645.376 100拥有更大的数据集:
markers = matrix(rep(c(1,0,0,0,0,2,0,0,0,0,1,0,0,0,3), times = 1000), ncol = 1)
#output
Unit: microseconds
expr min lq mean median uq max neval
mss(markers) 823.5 904.5025 1144.658 957.5945 1045.174 5455.24 100
evans(markers) 2940719.3 3185982.7470 3453372.766 3242533.4130 3299607.308 11652090.81 100发布于 2017-12-14 23:39:11
另一种方法是:
markers <- matrix(c(1,0,0,0,0,2,0,0,0,0,1,0,0,0,3), ncol = 1)创建一个包含所有可能滞后的dataframe版本的markers。
# Create dataframe of lagged vectors
require(dplyr);
df <- sapply(1:nrow(markers), function(i) lead(markers, i - 1));获取非滞后向量中的条目等于1的行索引。
# Select rows where entry = 1
idx <- which(df[, 1] == 1);
idx;
#[1] 1 11只保留那些对于行idx在any中存在一个条目等于2的索引( markers的滞后版本)。
# Keep only those rows where entry = 1 followed by a lagged 2
idx <- idx[sapply(idx, function(i) any(df[i, 2:nrow(df)] == 2, na.rm = TRUE))];最后,将这些行的值设置为9。
# Set those entries equal to 9
markers[idx, 1] <- 9;
markers;
# [,1]
# [1,] 9
# [2,] 0
# [3,] 0
# [4,] 0
# [5,] 0
# [6,] 2
# [7,] 0
# [8,] 0
# [9,] 0
#[10,] 0
#[11,] 1
#[12,] 0
#[13,] 0
#[14,] 0
#[15,] 3更新
在第二个markers示例中:
markers <- matrix(c(1,0,0,0,0,2,0,0,0,0,1,0,0,0,2,0,0,0,0,1,0,0,0,0,3), ncol = 1);
df <- sapply(1:nrow(markers), function(i) lead(markers, i - 1));
idx <- which(df[, 1] == 1);
idx <- idx[sapply(idx, function(i) any(df[i, 2:nrow(df)] == 2, na.rm = TRUE))];
markers[idx, 1] <- 9;
markers;
# [,1]
# [1,] 9
# [2,] 0
# [3,] 0
# [4,] 0
# [5,] 0
# [6,] 2
# [7,] 0
# [8,] 0
# [9,] 0
#[10,] 0
#[11,] 9
#[12,] 0
#[13,] 0
#[14,] 0
#[15,] 2
#[16,] 0
#[17,] 0
#[18,] 0
#[19,] 0
#[20,] 1
#[21,] 0
#[22,] 0
#[23,] 0
#[24,] 0
#[25,] 3https://stackoverflow.com/questions/47823452
复制相似问题