我如何用 R 总结这些数据?

How can I summarize this data with R?

我正在分析不同购物场所之间的客流。我有这样的数据:

df <- data.frame(customer.id=letters[seq(1,7)], 
                 shop.1=c(1,1,1,1,1,0,0),
                 shop.2=c(0,0,1,1,1,1,0),
                 shop.3=c(1,0,0,0,0,0,1))
df
#>   customer.id shop.1 shop.2 shop.3
#> 1           a      1      0      1
#> 2           b      1      0      0  
#> 3           c      1      1      0 
#> 4           d      1      1      0 
#> 5           e      1      1      0 
#> 6           f      0      1      0 
#> 7           g      0      0      1

因此,例如:

我想这样总结数据:

#>           shop.1 shop.2 shop.3 
#> shop.1         5      3      1
#> shop.2         3      4      0       
#> shop.3         1      0      2       

因此,例如,第 1 行显示:

我怎样才能做到这一点(请注意:我的数据集中有很多商店,因此首选可扩展的方法)?

您想列出 shop.* 个变量的 共现

df[,2:4] <- sapply(df[,2:4], function(x) { ifelse(x=="", 0, 1) } )

1) 据说可以使用 ftable(xtabs(...)) 来完成,但我为此苦苦挣扎了很长时间,却无法做到。我得到的最接近的是:

> ftable(xtabs(~ shop.1 + shop.2 + shop.3, df))

              shop.3 0 1
shop.1 shop.2           
0      0             0 1
       1             1 0
1      0             1 1
       1             3 0

2) 如@thelatemail 所示,您还可以:

# Transform your df from wide-form to long-form...
library(dplyr)
library(reshape2)
occurrence_df <- reshape2::melt(df, id.vars='customer.id') %>%
                 dplyr::filter(value==1)

   customer.id variable value
1            a   shop.1     1
2            b   shop.1     1
3            c   shop.1     1
4            d   shop.1     1
5            e   shop.1     1
6            c   shop.2     1
7            d   shop.2     1
8            e   shop.2     1
9            f   shop.2     1
10           a   shop.3     1
11           g   shop.3     1

我们真的可以在过滤器之后删除 value 列,这样我们就可以通过管道 %>% select(-value)

   customer.id variable
1            a   shop.1
2            b   shop.1
3            c   shop.1
4            d   shop.1
5            e   shop.1
6            c   shop.2
7            d   shop.2
8            e   shop.2
9            f   shop.2
10           a   shop.3
11           g   shop.3

# 然后与@thelatemail 的回答相同的交叉步骤:

crossprod(table(occurrence_df))

        variable
variable shop.1 shop.2 shop.3
  shop.1      5      3      1
  shop.2      3      4      0
  shop.3      1      0      2

(脚注:

  • 首先你的数据应该是数字(或因子),而不是字符串。您想将 "x" 转换为 1 并将 "" 转换为 0.
  • 如果它们是字符串,因为它们来自 read.csv,请使用 read.csv 参数 stringsAsFactors=TRUE 使它们成为因子,或 colClasses 使它们成为数字,并查看全部许多重复的问题。)

crossprod 可以处理您想做的事情,经过一些基本操作后将其分为 2 列,分别代表 customershop

tmp <- cbind(df[1],stack(df[-1]))
tmp <- tmp[tmp$values==1,]

crossprod(table(tmp[c(1,3)]))

#        ind
#ind      shop.1 shop.2 shop.3
#  shop.1      5      3      1
#  shop.2      3      4      0
#  shop.3      1      0      2

实际上,矩阵运算似乎就足够了,因为数据框只有01

首先,排除 customer.id 列并将 data.frame 更改为 matrix。这可能很容易。 (mydf 是您的数据框的名称。)

# base R way
as.matrix(mydf[,-1])
#>      shop.1 shop.2 shop.3
#> [1,]      1      0      1
#> [2,]      1      0      0
#> [3,]      1      1      0
#> [4,]      1      1      0
#> [5,]      1      1      0
#> [6,]      0      1      0
#> [7,]      0      0      1

library(dplyr) #dplyr way
(mymat <-
  mydf %>% 
  select(-customer.id) %>% 
  as.matrix())
#>      shop.1 shop.2 shop.3
#> [1,]      1      0      1
#> [2,]      1      0      0
#> [3,]      1      1      0
#> [4,]      1      1      0
#> [5,]      1      1      0
#> [6,]      0      1      0
#> [7,]      0      0      1

有了这个矩阵,只需进行如下矩阵运算即可。

t(mymat) %*% mymat
#>        shop.1 shop.2 shop.3
#> shop.1      5      3      1
#> shop.2      3      4      0
#> shop.3      1      0      2

你可以得到你的答案。