r - 如何将集合变成集合成员的指标?

标签 r postgresql dplyr

我拥有的数据针对每个观察都有一组“ flavor ”。我想将这些集合(在 PostgreSQL 中以 text[] 数组的形式存在)转换为指示各种口味是否存在的指标,因为我想检查口味是如何组合在一起或不组合在一起的.

我现在所拥有的是有效的,但实际上我想运行更复杂的变体,而且我有一种预感,我将数据放在一起的方式远没有它应该的那么优雅。我尝试使用 tidyrdplyr 包,但看不到如何应用它们。

有没有更好的方法(使用 R)?

下面是一些示例代码:

library("PostgreSQL")

pg <- dbConnect(PostgreSQL())

# Make the data set in the form I have it.
rs <- dbGetQuery(pg, "
     DROP TABLE IF EXISTS icecream ;

     CREATE TABLE icecream (id text, date date, flavours text[]);

     INSERT INTO icecream (id, date, flavours) VALUES 
     ('a', '2013-01-01', ARRAY['Chocolate', 'Vanilla']),
     ('b', '2013-01-01', ARRAY['Strawberry', 'Vanilla']),
     ('b', '2013-02-01', ARRAY['Raspberry', 'Lemon']),
     ('c', '2013-01-01', ARRAY['Raspberry', 'Blueberry']);")

# Get data in an R-friendly format
df <- dbGetQuery(pg, "    
     SELECT id, date, UNNEST(flavours) AS flavour
     FROM icecream;")

rs <- dbDisconnect(pg)

# Rearrange data and look at correlations
library(reshape2)
temp <- dcast(df, id + date ~ flavour, value.var="flavour")
temp[, -c(1,2)] <- !is.na(temp[, -c(1,2)])
cor(temp[, -c(1,2)])

这是数据最终的样子:

  id       date Blueberry Chocolate Lemon Raspberry Strawberry Vanilla
1  a 2013-01-01     FALSE      TRUE FALSE     FALSE      FALSE    TRUE
2  b 2013-01-01     FALSE     FALSE FALSE     FALSE       TRUE    TRUE
3  b 2013-02-01     FALSE     FALSE  TRUE      TRUE      FALSE   FALSE
4  c 2013-01-01      TRUE     FALSE FALSE      TRUE      FALSE   FALSE

下面是我想做的那种分析的例子:

> cor(temp[, -c(1,2)])
            Blueberry  Chocolate      Lemon  Raspberry Strawberry    Vanilla
Blueberry   1.0000000 -0.3333333 -0.3333333  0.5773503 -0.3333333 -0.5773503
Chocolate  -0.3333333  1.0000000 -0.3333333 -0.5773503 -0.3333333  0.5773503
Lemon      -0.3333333 -0.3333333  1.0000000  0.5773503 -0.3333333 -0.5773503
Raspberry   0.5773503 -0.5773503  0.5773503  1.0000000 -0.5773503 -1.0000000
Strawberry -0.3333333 -0.3333333 -0.3333333 -0.5773503  1.0000000  0.5773503
Vanilla    -0.5773503  0.5773503 -0.5773503 -1.0000000  0.5773503  1.0000000

要跳过 PostgreSQL,我想可以使用此信息将 df 放在一起。我包括 PostgreSQL 以防万一更优雅的解决方案更有效地使用 PostgreSQL。

dput(df)
structure(list(id = c("a", "a", "b", "b", "b", "b", "c", "c"), 
    date = structure(c(15706, 15706, 15706, 15706, 15737, 15737, 
    15706, 15706), class = "Date"), flavour = c("Chocolate", 
    "Vanilla", "Strawberry", "Vanilla", "Raspberry", "Lemon", 
    "Raspberry", "Blueberry")), .Names = c("id", "date", "flavour"
), row.names = c(NA, 8L), class = "data.frame")

最佳答案

任何 postgres 解决方案都会变得不那么优雅。您必须使用 crosstab,这将需要为您的每种风格定义列。

这是使用 dplyrtidyr 的方法:

library(dplyr)
library(tidyr)
df %>%
    mutate_(indicator=~TRUE) %>%
    spread('flavour', 'indicator', fill=FALSE)

关于r - 如何将集合变成集合成员的指标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30403546/

相关文章:

r - 如何从 e1071 包中运行 svm 获取预测列表

sql - 部分不同的选择

r - 从 dplyr 中以空格分隔的字符串中提取第 n 个位置

R:如何阻止看门人中的装饰函数更改次要字符列?

r - 使两个不同长度的向量长度相等

regex - r- 多重匹配中的部分匹配

r - r中使用prewhiten函数出错

postgresql - 如何传递 ENUM 变量作为 POSTGRESQL 函数的输入

postgresql - 使用 Sequelize 和 PostgreSQL 设置数据库连接

r - tidyr 传播后如何控制新变量的名称?