我有一个数据集,简化版如下:
input <- data_frame(key=c(1,2),Color=c("Red,Green","Blue,Red"))
input
key Color
1 Red,Green
2 Blue,Red
我想使用Color列创建额外的功能,如下所示:
key Color.Red Color.Green Color.Blue
1 TRUE TRUE FALSE
2 TRUE FALSE TRUE
如何在R中执行此操作?我正在研究重塑方法。但似乎这是一个不同的情况。
答案 0 :(得分:6)
通过dplyr
和tidyr
library(dplyr)
library(tidyr)
input %>%
unnest(Color = strsplit(Color, ',')) %>%
group_by(key) %>%
mutate(new = TRUE) %>%
spread(Color, new, fill = FALSE) %>%
ungroup()
#Source: local data frame [2 x 4]
#Groups: key [2]
# key Blue Green Red
# <dbl> <lgl> <lgl> <lgl>
#1 1 FALSE TRUE TRUE
#2 2 TRUE FALSE TRUE
答案 1 :(得分:2)
dplyr
和stringr
解决方案作为Sotos的替代品,如果您已经知道允许使用哪种颜色,则可以使用dplyr
和stringr
解决方案:
library(dplyr)
library(stringr)
input %>%
mutate(
Color.Red = str_detect(Color, "Red"),
Color.Green = str_detect(Color, "Green"),
Color.Blue = str_detect(Color, "Blue")
) %>%
select(-Color)
如果您正在寻找速度,基本R通常会快一点,在这种情况下,您可以使用for循环来处理列创建:
allowed_colors <- c("Red", "Green", "Blue") # Pre-populate this
for (c in allowed_colors) {
input[[paste0("Color.", c)]] <- grepl(c, input$Color)
}
input$Color <- NULL
答案 2 :(得分:2)
我们可以使用mtabulate
以简洁的方式轻松完成此操作。按,
拆分“颜色”,使用mtabulate
(来自qdapTools
)获取频率,转换为逻辑矩阵(!=0
)和cbind
原始数据的第一列
library(qdapTools)
cbind(input[1], mtabulate(strsplit(input$Color,","))!=0)
# key Blue Green Red
#1 1 FALSE TRUE TRUE
#2 2 TRUE FALSE TRUE
答案 3 :(得分:0)
以下是dplyr
和tidyr
的另一个想法:
input %>%
separate(Color, c("Color1", "Color2"), sep = ",") %>%
mutate(Color.Red = if_else(Color1 == "Red" | Color2 == "Red", TRUE, FALSE)) %>%
mutate(Color.Green = if_else(Color1 == "Green" | Color2=="Green", TRUE, FALSE)) %>%
mutate(Color.Blue = if_else(Color1 == "Blue" | Color2 == "Blue", TRUE, FALSE)) %>%
select(-Color1, -Color2)
答案 4 :(得分:0)
我曾经写过很多R代码,但是几年没有这样做了。这里有一些快速代码可以给你一些想法。我相信你可以修改代码以满足你的需求。
input <- data.frame(key=c(1,2),Color=c("Red,Green","Blue,Red"))
colors <- c(1, 2, 3)
names(colors) <- c('Red', 'Green', 'Blue')
f <- function(row)
{
v <- c(FALSE, FALSE, FALSE)
for(word in strsplit(row[2],','))
{
v[colors[word]] = TRUE
}
data.frame(c(row[1],v))
}
df = t(data.frame(apply(input, 1, f)))
print(df)