我需要对包含位字符串的tibble列执行按位运算。例如,我希望能够做类似
的事情ds <- tibble(Id=1:2, X1=c("001", "011"), X2=c("101", "110"))
mutate(ds, X1andX2 = magic.AND(X1,X2))
获取
# A tibble: 2 x 4
Id X1 X2 X1andX2
<int> <chr> <chr> <chr>
1 1 001 101 001
2 2 011 110 010
我正在操作不是特别大的数据集(~50k行),但我必须多次执行此操作。所以,我正在寻找或多或少有效和简单的东西。
由于我必须运行许多连接和组操作,我更喜欢与dplyr兼容的方法。
编辑抱歉,上面的示例不是很好,因为三位字符串在转换为整数和填充0之后会产生看起来像三位字符串的结果(请参阅Sotos&#39; s回答几乎有效)。此外,很高兴看到长字符串的解决方案,即超过32位。这是一个更好的例子。
ds <- tibble(Id=1:2, X1=c("0101", "1110"), X2=c("1110", "0110"))
输出
# A tibble: 2 x 4
Id X1 X2 X1andX2
<int> <chr> <chr> <chr>
1 1 0101 1110 0100
2 2 1110 0110 0110
答案 0 :(得分:1)
包bitops
使这些操作变得简单,
library(bitops)
ds$X1_X2 <- sprintf('%03d', bitAnd(ds$X1, ds$X2))
ds
# A tibble: 2 x 4
# Id X1 X2 X1_X2
# <int> <chr> <chr> <chr>
#1 1 001 101 001
#2 2 011 110 010
答案 1 :(得分:0)
我放弃了一个简单的解决方案。按照Konrad Rudolph的建议,我写了两个转换函数。第一个是受 atesghnagfbvgfr's answer to another question的启发。
intToBitStr <- Vectorize(function(x, bitN) {
i <- 0
v <- integer(bitN)
while(x > 0) {
v[bitN - i] <- x %% 2
x <- x %/% 2
i <- i + 1
}
return(paste0(v, collapse=""))
}, c("x"), USE.NAMES = F)
bitStrToInt <- Vectorize(function(x) {
v <- rev(as.integer(strsplit(x, "")[[1]]))
acc <- 0
for (i in 1:length(v)) {
acc <- acc + v[i] * 2^(i - 1)
}
return(acc)
}, USE.NAMES = F)
使用这两个函数,解决方案就像
mutate(ds, X1Int = bitStrToInt(X1), X2Int = bitStrToInt(X2)) %>%
mutate(X1andX2 = intToBitStr(bitwAnd(X1Int, X2Int), bitN=4)) %>%
select(-X1Int, -X2Int)
可能效率不高,我还没有测试过。如果它太慢了,我只会用Perl编写所有内容。