如何根据值数据在R中创建新列?

时间:2017-01-21 15:06:55

标签: r dplyr

我有一个数据集,简化版如下:

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中执行此操作?我正在研究重塑方法。但似乎这是一个不同的情况。

5 个答案:

答案 0 :(得分:6)

通过dplyrtidyr

提出了一个想法
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)

dplyrstringr解决方案

作为Sotos的替代品,如果您已经知道允许使用哪种颜色,则可以使用dplyrstringr解决方案:

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溶液

如果您正在寻找速度,基本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)

以下是dplyrtidyr的另一个想法:

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)