如何从数据框中的列和 cbind() 到数据框创建多列
How to create multiple columns from a column in data frame and cbind() to dataframe
我在数据框中有一列由 8 位位掩码组成。我想 'explode' 这到我的数据框中的 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))
但我显然做错了什么,因为当我尝试使用 head(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
基数 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 更新后的答案好多了。
我在数据框中有一列由 8 位位掩码组成。我想 'explode' 这到我的数据框中的 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))
但我显然做错了什么,因为当我尝试使用 head(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
基数 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 更新后的答案好多了。