我有以下数据框:
id keywords
--- --------
1 Red
2 Red, Blue
3 Green, Blue
我想重塑它:
id Red Blue Green
--- ----- ----- -----
1 T F F
2 T T F
3 F T T
有什么想法吗?
答案 0 :(得分:4)
将字符串拆分为子字符串后,您可以从mtabulate
尝试qdapTools
library(qdapTools)
data.frame(id=df1$id,!!mtabulate(strsplit(df1$keywords, ', ')))
# id Blue Green Red
#1 1 FALSE FALSE TRUE
#2 2 TRUE FALSE TRUE
#3 3 TRUE TRUE FALSE
或使用base R
data.frame(id=df1$id,!!t(sapply(strsplit(df1$keywords, ', '),
function(x) table(factor(x, levels=c('Red', 'Blue', 'Green'))))))
# id Red Blue Green
#1 1 TRUE FALSE FALSE
#2 2 TRUE TRUE FALSE
#3 3 FALSE TRUE TRUE
答案 1 :(得分:3)
# using R base
#
# your data
d <- data.frame(
id=1:3,
keywords=c('Red','Red,Blue','Green,Blue'),
stringsAsFactors=F)
#
cls <- unique(unlist(strsplit(d$keywords,split=',')))
dl <- sapply(cls,function(n)sapply(d$keywords,grepl,pattern=n))
# print result
d <- cbind(d,dl)
d
id keywords Red Blue Green
1 1 Red TRUE FALSE FALSE
2 2 Red,Blue TRUE TRUE FALSE
3 3 Green,Blue FALSE TRUE TRUE
# d$Green is atomic
答案 2 :(得分:2)
这是另一种可能的方法
## vector for matching
nm <- c("Red", "Blue", "Green")
dc <- do.call(rbind, lapply(strsplit(df$keywords, ", "), function(x) {
length(x) <- nrow(df)
setNames(nm %in% x, nm)
}))
cbind(df[1], dc)
# id Red Blue Green
# 1 1 TRUE FALSE FALSE
# 2 2 TRUE TRUE FALSE
# 3 3 FALSE TRUE TRUE
更新:这是使用stringi
包中的函数的更短,更有效的方法
mat <- vapply(nm, stringi::stri_detect_fixed, logical(3L), str = df$keywords)
cbind(df[1], mat)
# id Red Blue Green
# 1 1 TRUE FALSE FALSE
# 2 2 TRUE TRUE FALSE
# 3 3 FALSE TRUE TRUE
答案 3 :(得分:1)
dplyr
的解决方案:
library(dplyr)
df %>%
#just one mutate function really needed as below
mutate(Red = grepl('Red' , df$keywords),
Blue = grepl('Blue' , df$keywords),
Green= grepl('Green', df$keywords)) %>%
#select the columns you need
select(id, Red, Blue, Green)
输出:
id Red Blue Green
1 1 TRUE FALSE FALSE
2 2 TRUE TRUE FALSE
3 3 FALSE TRUE TRUE
如果你有很多变数,或者另一种选择:
keywords <- c('Red', 'Blue', 'Green')
#one lapply function
df2 <-do.call(data.frame, lapply(keywords, function(x) grepl(x, df$keywords)))
colnames(df2) <- keywords
df <- cbind(df[-2], df2)
输出:
> df
id Red Blue Green
1 1 TRUE FALSE FALSE
2 2 TRUE TRUE FALSE
3 3 FALSE TRUE TRUE
答案 4 :(得分:0)
我的&#34; splitstackshape&#34;中的cSplit_e
函数包执行此操作(转换为1和0而不是TRUE
和FALSE
s):
library(splitstackshape)
cSplit_e(d, "keywords", ",", type = "character", fill = 0)
# id keywords keywords_Blue keywords_Green keywords_Red
# 1 1 Red 0 0 1
# 2 2 Red,Blue 1 0 1
# 3 3 Green,Blue 1 1 0
如果要删除原始列,还有一个drop
参数。