翻转字符串向量中的二进制数字而不在 R 中循环
Flipping binary figures in a string vector without looping in R
我有一个大小相等的 0/1 元素向量,dna。和一个具有相同大小的类似向量,翻转。如果flip = 1,我想翻转dna向量中的相应图形。所以 0 会变成 1 而 1 会变成 0。并且没有循环来让它变快。我的真实数据集有很多数据。
以下是一些示例数据:
#input
dna = c('0101010100', '1010101010', '1010101011')
flip = c('0100000001', '0000000000', '1000000000')
#requested answer
dna_flipped = c('0001010101', '1010101010', '0010101011')
#first element: second and 10th character is flipped
#second element: nothing is changed
#third element: first character is changed
#try loop solution
flip_split = lapply(strsplit(flip, ''), function(x) which(x == '1'))
for (i in 1:length(dna)){
for(j in seq_along(flip_split[[i]])){
k = flip_split[[i]][j]
substring(dna[[i]],k,k) = as.character(abs(1 - as.integer(substring(dna[[i]],k,k))))
}
}
没有循环怎么能做到这一点?
我认为你描述的逻辑等同于逻辑异或。困难的部分是将其应用于字符串。以下应该有效,并且每个元素的向量化最少,因此您不需要遍历单个字符:
unname(unlist(Map(function(a, b) {
paste(as.numeric(xor(as.numeric(charToRaw(a)) - 48 == 1,
as.numeric(charToRaw(b)) - 48 == 1)), collapse = "")
}, a = dna, b = flip)))
#> [1] "0001010101" "1010101010" "0010101011"
或者,也许更有效,正如 Ritchie Sacramento 指出的那样:
unname(unlist(Map(function(a, b) {
rawToChar(as.raw(as.numeric(xor(as.numeric(charToRaw(a)) - 48 == 1,
as.numeric(charToRaw(b)) - 48 == 1)) + 48))
}, a = dna, b = flip)))
#> [1] "0001010101" "1010101010" "0010101011"
我有一个大小相等的 0/1 元素向量,dna。和一个具有相同大小的类似向量,翻转。如果flip = 1,我想翻转dna向量中的相应图形。所以 0 会变成 1 而 1 会变成 0。并且没有循环来让它变快。我的真实数据集有很多数据。 以下是一些示例数据:
#input
dna = c('0101010100', '1010101010', '1010101011')
flip = c('0100000001', '0000000000', '1000000000')
#requested answer
dna_flipped = c('0001010101', '1010101010', '0010101011')
#first element: second and 10th character is flipped
#second element: nothing is changed
#third element: first character is changed
#try loop solution
flip_split = lapply(strsplit(flip, ''), function(x) which(x == '1'))
for (i in 1:length(dna)){
for(j in seq_along(flip_split[[i]])){
k = flip_split[[i]][j]
substring(dna[[i]],k,k) = as.character(abs(1 - as.integer(substring(dna[[i]],k,k))))
}
}
没有循环怎么能做到这一点?
我认为你描述的逻辑等同于逻辑异或。困难的部分是将其应用于字符串。以下应该有效,并且每个元素的向量化最少,因此您不需要遍历单个字符:
unname(unlist(Map(function(a, b) {
paste(as.numeric(xor(as.numeric(charToRaw(a)) - 48 == 1,
as.numeric(charToRaw(b)) - 48 == 1)), collapse = "")
}, a = dna, b = flip)))
#> [1] "0001010101" "1010101010" "0010101011"
或者,也许更有效,正如 Ritchie Sacramento 指出的那样:
unname(unlist(Map(function(a, b) {
rawToChar(as.raw(as.numeric(xor(as.numeric(charToRaw(a)) - 48 == 1,
as.numeric(charToRaw(b)) - 48 == 1)) + 48))
}, a = dna, b = flip)))
#> [1] "0001010101" "1010101010" "0010101011"