Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
生成所有可能的对,并在R中计数频率_R_Dplyr - Fatal编程技术网

生成所有可能的对,并在R中计数频率

生成所有可能的对,并在R中计数频率,r,dplyr,R,Dplyr,我有一个产品(苹果、梨、香蕉)的数据框架,这些产品在不同的地点(城市)销售,属于不同的类别(食品和食用品) 我想数一数任何一对产品在任何类别中出现在一起的次数 这是一个示例数据集,我正在尝试使用它: category <- c('food','food','food','food','food','food','edibles','edibles','edibles','edibles', 'edibles') location <- c('houston, TX', 'housto

我有一个产品(苹果、梨、香蕉)的数据框架,这些产品在不同的地点(城市)销售,属于不同的类别(食品和食用品)

我想数一数任何一对产品在任何类别中出现在一起的次数

这是一个示例数据集,我正在尝试使用它:

category <- c('food','food','food','food','food','food','edibles','edibles','edibles','edibles', 'edibles')
location <- c('houston, TX', 'houston, TX', 'las vegas, NV', 'las vegas, NV', 'philadelphia, PA', 'philadelphia, PA', 'austin, TX', 'austin, TX', 'charlotte, NC', 'charlotte, NC', 'charlotte, NC')
item <- c('apple', 'banana', 'apple', 'pear', 'apple', 'pear', 'pear', 'apple', 'apple', 'pear', 'banana')

food_data <- data.frame(cbind(category, location, item), stringsAsFactors = FALSE)

category来自
tidyverse
的解决方案。其想法是创建
食品数据2
,这是
食品数据的广泛格式。然后,在每个唯一项目之间创建组合,并使用
map2\u int
循环遍历每个项目组合以计算数字。此解决方案适用于任何数量的项目

library(tidyverse)

food_data2 <- food_data %>%
  mutate(count = 1) %>%
  spread(item, count, fill = 0) 

food_combination <- food_data %>%
  pull(item) %>%
  unique() %>%
  combn(2) %>%
  t() %>%
  as_data_frame() %>%
  mutate(count = map2_int(V1, V2, 
                         ~sum(apply(food_data2 %>% select(.x, .y), 1, sum) == 2)))

# View the result
food_combination
# A tibble: 3 x 3
      V1     V2 count
   <chr>  <chr> <int>
1  apple banana     2
2  apple   pear     4
3 banana   pear     1

来自
tidyverse
的解决方案。其想法是创建
食品数据2
,这是
食品数据的广泛格式。然后,在每个唯一项目之间创建组合,并使用
map2\u int
循环遍历每个项目组合以计算数字。此解决方案适用于任何数量的项目

library(tidyverse)

food_data2 <- food_data %>%
  mutate(count = 1) %>%
  spread(item, count, fill = 0) 

food_combination <- food_data %>%
  pull(item) %>%
  unique() %>%
  combn(2) %>%
  t() %>%
  as_data_frame() %>%
  mutate(count = map2_int(V1, V2, 
                         ~sum(apply(food_data2 %>% select(.x, .y), 1, sum) == 2)))

# View the result
food_combination
# A tibble: 3 x 3
      V1     V2 count
   <chr>  <chr> <int>
1  apple banana     2
2  apple   pear     4
3 banana   pear     1

下面是使用
tidyverse
crossprod
的一种方法;通过使用
spread
,它将来自同一类别位置组合的所有项目/水果转换为一行,项目作为标题(这要求每个类别国家/地区没有重复的项目,否则需要预聚合步骤),值指示存在
crossprod
主要计算项目对列的内积,并给出共现数

library(tidyverse)
food_data %>% 
    mutate(n = 1) %>% 
    spread(item, n, fill=0) %>% 
    select(-category, -location) %>% 
    {crossprod(as.matrix(.))} %>% 
    `diag<-`(0)

#       apple banana pear
#apple      0      2    4
#banana     2      0    1
#pear       4      1    0

下面是使用
tidyverse
crossprod
的一种方法;通过使用
spread
,它将来自同一类别位置组合的所有项目/水果转换为一行,项目作为标题(这要求每个类别国家/地区没有重复的项目,否则需要预聚合步骤),值指示存在
crossprod
主要计算项目对列的内积,并给出共现数

library(tidyverse)
food_data %>% 
    mutate(n = 1) %>% 
    spread(item, n, fill=0) %>% 
    select(-category, -location) %>% 
    {crossprod(as.matrix(.))} %>% 
    `diag<-`(0)

#       apple banana pear
#apple      0      2    4
#banana     2      0    1
#pear       4      1    0

这里有一个小函数,可以满足您的需要。它可以通过
dplyr::
评估系统推广到任意分组列。可能是更好的方法,但这是有效的:p

评论/解释是内联的~~

library("dplyr")

# a function to apply to `food_data` from the original post 
count_combos <- function(df, group_col1, group_col2, count_col){ 

  # use `combn()` to get all the unique pairs from the `$items` col
  combos <- t(combn(sort(unique(df[[count_col]])), 2)) %>% 
    as_data_frame() %>% 
    # initialize an empty column to catch the counts 
    mutate(count=NA)

  # create a new df from the colnames passed as args, 
  # (it would be more general to just use the dplyr evaluation system (@_@))
  df <- data_frame(
    group_col1 = df[[group_col1]],
    group_col2 = df[[group_col2]],
    count_col  = df[[count_col]]
  )
  # for each combo of the grouping vars, get a pipe-seperated string of items
  df <- df %>% 
    group_by(group_col1, group_col2) %>% summarize(
      items = paste(unique(count_col), collapse="|")
    ) %>% ungroup()

  # for each item pair/combo, get the number of rows of `df` with both items 
  combos$count <- sapply(1:nrow(combos), function(x){
    sum(grepl(combos$V1[x], df$items) & grepl(combos$V2[x], df$items))
  })
  # and return it in a nice df
  return(combos)
}

# apply the function 
count_combos(food_data, 
             group_col1="category", group_col2="location", count_col="item")
库(“dplyr”)
#一个应用于原始帖子中“food_data”的函数
计数\u组合%
#初始化空列以捕获计数
变异(计数=NA)
#从作为args传递的colnames创建新的df,
#(更一般的做法是只使用dplyr评估系统)
df%汇总(
项目=粘贴(唯一(计数列),折叠=“|”)
)%%>%ungroup()
#对于每个项目对/组合,获取两个项目的“df”行数

combos$count这里有一个小函数,可以满足您的需要。它可以通过
dplyr::
评估系统推广到任意分组列。可能是更好的方法,但这是有效的:p

评论/解释是内联的~~

library("dplyr")

# a function to apply to `food_data` from the original post 
count_combos <- function(df, group_col1, group_col2, count_col){ 

  # use `combn()` to get all the unique pairs from the `$items` col
  combos <- t(combn(sort(unique(df[[count_col]])), 2)) %>% 
    as_data_frame() %>% 
    # initialize an empty column to catch the counts 
    mutate(count=NA)

  # create a new df from the colnames passed as args, 
  # (it would be more general to just use the dplyr evaluation system (@_@))
  df <- data_frame(
    group_col1 = df[[group_col1]],
    group_col2 = df[[group_col2]],
    count_col  = df[[count_col]]
  )
  # for each combo of the grouping vars, get a pipe-seperated string of items
  df <- df %>% 
    group_by(group_col1, group_col2) %>% summarize(
      items = paste(unique(count_col), collapse="|")
    ) %>% ungroup()

  # for each item pair/combo, get the number of rows of `df` with both items 
  combos$count <- sapply(1:nrow(combos), function(x){
    sum(grepl(combos$V1[x], df$items) & grepl(combos$V2[x], df$items))
  })
  # and return it in a nice df
  return(combos)
}

# apply the function 
count_combos(food_data, 
             group_col1="category", group_col2="location", count_col="item")
库(“dplyr”)
#一个应用于原始帖子中“food_data”的函数
计数\u组合%
#初始化空列以捕获计数
变异(计数=NA)
#从作为args传递的colnames创建新的df,
#(更一般的做法是只使用dplyr评估系统)
df%汇总(
项目=粘贴(唯一(计数列),折叠=“|”)
)%%>%ungroup()
#对于每个项目对/组合,获取两个项目的“df”行数

combos$count在我的真实数据集中,我有数百个不同的项目,所以我无法像这样手动生成对名称:/@HarryM谢谢你的评论。我已更新了我的答案,该答案适用于任何数量的项目,而无需手动指定列名。在我的真实数据集中,我有数百个不同的项目,因此我无法像下面这样手动生成对名称:/@HarryM感谢您的评论。我已经更新了我的答案,它应该适用于任何数量的项目,而无需手动指定列名。这看起来非常整洁!在我的实际数据集中,我有数百个不同的项目。有没有一种简单的方法可以将这个矩阵折叠成一个数据帧,其中第一列是数据对的名称,第二列是该数据对的计数?如果您不关心按交换顺序复制的数据对,可以将
%%>%as.data.frame.table()链接起来
仅将矩阵转换为数据帧。我想输出像第1行:苹果,香蕉,2;第二排:苹果,梨,4我一开始搞错了。它应该是
as.data.frame.table
而不是
as.data.frame
。这看起来非常整洁!在我的实际数据集中,我有数百个不同的项目。有没有一种简单的方法可以将这个矩阵折叠成一个数据帧,其中第一列是数据对的名称,第二列是该数据对的计数?如果您不关心按交换顺序复制的数据对,可以将
%%>%as.data.frame.table()链接起来
仅将矩阵转换为数据帧。我想输出像第1行:苹果,香蕉,2;第二排:苹果,梨,4我一开始搞错了。它应该是
as.data.frame.table
而不是
as.data.frame
。避免所有重塑可以简化为
crossprod(table(food_data[-1])
。然后,如果需要,您可以使用
diag
将对角线设置为零。重新规划所有形状可以简化为
crossprod(表(食品数据[-1])
。然后,如果需要,可以使用
diag
将对角线设置为零