我在数据帧中有一个列,由8位位掩码组成。我想在我的数据框架中"爆炸"到8个新列。位掩码定义为:
mask <- c('term1'=1,'term2'=2,'term3'=4,'term4'=8,...) #etc
到最后,我希望在我的数据框中有8个名为term1到term8的新列,其中有一个TRUE/FALSE值,表示是否设置了位。例如,使用3位掩码:
id bitmask
a 1
b 4
c 5
将会出现:
id bitmask term1 term2 term3
a 1 TRUE FALSE FALSE
b 4 FALSE FALSE TRUE
c 5 TRUE FALSE TRUE
我已经写出了创建位掩码列值的函数:
addl <- as.data.frame(sapply(data$bitmask, function(x) bitwAnd(x,mask) > 0))
但我显然做错了,因为当我试图看到使用头(addl)的结果,它只是挂起。我甚至还没有讲到cbind()或设置列名。任何帮助理解我做错了什么将非常感激!
在base R中设置数据:
mask <- c('term1'=1,'term2'=2,'term3'=4)
df <- data.frame(id = c(letters[1:3]), bitmask = c(1,4,5))
cbind(df, sapply(mask, bitwAnd, df$bitmask) > 0)
# id bitmask term1 term2 term3
# 1 a 1 TRUE FALSE FALSE
# 2 b 4 FALSE FALSE TRUE
# 3 c 5 TRUE FALSE TRUE
或与data.table
可以做:
require(data.table)
dt <- as.data.frame(df)
data.table(dt, dt[,sapply(mask, bitwAnd, bitmask)] > 0)
# id bitmask term1 term2 term3
# 1: a 1 TRUE FALSE FALSE
# 2: b 4 FALSE FALSE TRUE
# 3: c 5 TRUE FALSE TRUE
Base R:
mask <- c('term1'=1,'term2'=2,'term3'=4,'term4'=8)
dat <- data.frame(id=letters[1:3], bitmask=c(1, 4, 5), stringsAsFactors=FALSE)
cbind(dat, do.call(rbind, lapply(dat$bitmask, function(x) {
setNames(rbind.data.frame(bitwAnd(x, mask)>0), names(mask))
})))
## id bitmask term1 term2 term3 term4
## 1 a 1 TRUE FALSE FALSE FALSE
## 2 b 4 FALSE FALSE TRUE FALSE
## 3 c 5 TRUE FALSE TRUE FALSE
但是Gary更新的答案要好得多。