【问题标题】:How to create pairs from a single column counting the occurrence in R?如何从计算 R 中出现次数的单列创建对?
【发布时间】:2021-11-15 21:47:46
【问题描述】:

所以我正在为基于 IMDb 数据的社交网络分析创建一个边缘文件。 我遇到了一个问题,我不知道如何解决它,因为我是 R 新手。

假设我有以下数据框:

movieID <- c('A', 'A','A', 'B','B', 'C','C', 'C')
crewID <- c('Z', 'Y', 'X', 'Z','V','V', 'X', 'Y')
rating <- c('7.3','7.3', '7.3', '2.1', '2.1', '9.0','9.0', '9.0')
df <- data.frame(movieID, crewID, rating)
movieID CrewID Rating
A Z 7.3
A Y 7.3
A X 7.3
B Z 2.1
B V 2.1
C V 9.0
C X 9.0
C Y 9.0

我正在尝试在电影中构建独特的 CrewID 对,其权重等于该对的出现次数,这意味着这两个工作人员一起制作电影的频率。所以基本上我想要一个像下面这样的数据框:

CrewID1 CrewID2 weight (not a col but explanation)
Z Y 1 together once in movie A
Z X 1 together once in movie A
Y X 2 together twice in movies A and C
Z V 1 together once in movie B
V X 1 together once in movie C
V Y 1 together once in movie C

(Z,Y) 和 (Y,Z) 对彼此相等,因为我不关心方向。

我在类似的问题上找到了以下 StackOverflow 线程: How to create pairs from a single column based on order of occurrence in R?

但是在我的情况下,这会跳过 (V,Y) 和 (X,Z) 的组合,并且 (X,Y) 的计数仍然是 1,我不知道如何解决它。

【问题讨论】:

  • 你能和dput分享你的第一个data.frame吗?这将使人们更容易为您提供帮助,因为他们可以复制粘贴代码以读取您的数据的 sn-p。

标签: r network-analysis edge-list


【解决方案1】:
m <- crossprod(table(df[-3]))
m[upper.tri(m, diag = TRUE)] <-0
subset(as.data.frame.table(m), Freq > 0)

   CrewID CrewID.1 Freq
2       X        V    1
3       Y        V    1
4       Z        V    1
7       Y        X    2
8       Z        X    1
12      Z        Y    1

【讨论】:

  • 不太确定我是否理解您的回答。这似乎给了我一个空矩阵......你能详细说明一下吗?
  • @Christine 空矩阵是什么意思?这给出了预期的结果
  • 如果我有一个包含movieID列的数据框 0) 我得到一个包含 A、B、C 行和 A、B、C 列的表格,每个条目都是 0。
  • @Christine,你能再检查一次吗,因为在完全按照呈现的方式运行代码之后,我得到了如上所示的正确值。你一定做错了什么。 subset 函数本身获取大于 0 的值。因此,最终结果中不可能有 0 条目
  • 是的,如果我只运行代码的第一行 if 返回一个包含 A、B、C 行和 A、B、C 列且 (A,A) 为 9 的表,(B, B) 是 4,(C,C) 是 9。其他值为 0。只要我运行代码的第二行,我就会得到我之前描述的结果 - 一个空表,显然不会被最后一行代码。
【解决方案2】:

也许不是最有效的解决方案,但这是一种方法:

# Define a function that generates pairs of ids
make_pairs <- function(data){
# Extract all ids in the movie
data$crew %>% 
    # Organize them alphabetically
    sort() %>% 
    # Generate all unique pairs
    combn(2) %>% 
    # Prep for map
    as.data.frame() %>% 
    # Generate pairs as single string
    purrr::map_chr(str_flatten, '_')
}
# Generate the data
tibble::tibble(
movie = c('A', 'A', 'A', 'B','B', "C", 'C', 'C'),
crew = c('Z', 'Y', 'X', 'Z', 'V', 'V', 'X', 'Y')
) %>% 
    # Nest the data so all ids in one movie gets put together
    tidyr::nest(data = -movie) %>%
    # Generate pairs of interactions
        dplyr::mutate(
        pairs = purrr::map(data, make_pairs)
    ) %>% 
    # Expand all pairs
    tidyr::unnest(cols = pairs) %>% 
    # Separate them into unique colums
    tidyr::separate(pairs, c('id1', 'id2')) %>% 
    # Count the number of times two ids co-occure
    dplyr::count(id1, id2)

# A tibble: 6 x 3
  id1   id2       n
  <chr> <chr> <int>
1 V     X         1
2 V     Y         1
3 V     Z         1
4 X     Y         2
5 X     Z         1
6 Y     Z         1

【讨论】:

  • 谢谢!您可能是对的 - 不一定是我假设的最有效的解决方案,但它正在工作,这比我能生产的要好。感谢您的帮助和时间:)
  • 它在小数据集上运行良好,但是,当我使用我的大数据集时,我收到错误“错误:mutate()pairs 的问题。我pairs = purrr::map(data, make_pairs)。 x n
  • @Christine 这意味着一部电影的工作人员少于 2 人。我建议先过滤掉它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多