获取唯一元素的所有索引

Get all the indices of unique elements

我有一个包含 500 000 个条目的数据集。其中的每个条目都有一个 userId 和一个 productId。我想获取与每个不同的 productIds 对应的所有 userIds。但是列表太大了,none 下面的方法对我有用,速度很慢。有没有更快的解决方案。

使用lapply:(问题:遍历每个 uniqPids 元素的整个 rpid 列表)

orderedIndx <- lapply(uniqPids, function(x){
    which(rpid %in% x)
})
names(orderedIndx) <- uniqPids
#Looking for indices with each unique productIds

使用For循环:

  orderedIndx <- list()
  for(j in 1:length(rpid)){
    existing <- length(orderedIndx[rpid[j]])
    orderedIndx[rpid[j]][existing + 1] <- j
  }

示例数据:

ruid[1:10]
# [1] "a3sgxh7auhu8gw" "a1d87f6zcve5nk" "abxlmwjixxain"  "a395borc6fgvxv" "a1uqrsclf8gw1t" "adt0srk1mgoeu" 
 [7] "a1sp2kvkfxxru1" "a3jrgqveqn31iq" "a1mzyo9tzk0bbi" "a21bt40vzccyt4"

rpid[1:10]
# [1] "b001e4kfg0" "b001e4kfg0" "b000lqoch0" "b000ua0qiq" "b006k2zz7k" "b006k2zz7k" "b006k2zz7k" "b006k2zz7k"
 [9] "b000e7l2r4" "b00171apva"

输出应该是这样的:

b001e4kfg0 -> a3sgxh7auhu8gw, a1d87f6zcve5nk
b000lqoch0 -> abxlmwjixxain
b000ua0qiq -> a395borc6fgvxv
b006k2zz7k -> a1uqrsclf8gw1t, adt0srk1mgoeu, a1sp2kvkfxxru1, a3jrgqveqn31iq
b000e7l2r4 -> a1mzyo9tzk0bbi
b00171apva -> a21bt40vzccyt4

您的数据框中是否有整齐的数据?然后你就可以这样做了。

library(dplyr)

df %>%
  select(productId, userId) %>%
  distinct

看来您可能只是在寻找 split?

split(seq_along(rpid), rpid)

不确定你想要什么类型的输出,或者你的数据集中有多少行,但我建议使用 3 个版本,你可以选择你喜欢的那个。第一个版本使用 dplyr 和字符值作为变量。如果您有数百万行,我预计这会很慢。第二个版本使用 dplyr 但因子变量。我希望这比上一个更快。第三个版本使用 data.table。我希望这与第二个版本一样快,或者更快。

library(dplyr)

ruid = 
c("a3sgxh7auhu8gw", "a1d87f6zcve5nk", "abxlmwjixxain",  "a395borc6fgvxv",
  "a1uqrsclf8gw1t", "adt0srk1mgoeu", "a1sp2kvkfxxru1", "a3jrgqveqn31iq",
  "a1mzyo9tzk0bbi", "a21bt40vzccyt4")

rpid =
c("b001e4kfg0", "b001e4kfg0", "b000lqoch0", "b000ua0qiq", "b006k2zz7k",
  "b006k2zz7k", "b006k2zz7k", "b006k2zz7k", "b000e7l2r4", "b00171apva")

### using dplyr and character values
dt = data.frame(rpid, ruid, stringsAsFactors = F)

dt %>%
  group_by(rpid) %>%
  do(data.frame(list_ruids = paste(c(.$ruid), collapse=", "))) %>%
  ungroup

#         rpid                                                    list_ruids
#        (chr)                                                         (chr)
# 1 b000e7l2r4                                                a1mzyo9tzk0bbi
# 2 b000lqoch0                                                 abxlmwjixxain
# 3 b000ua0qiq                                                a395borc6fgvxv
# 4 b00171apva                                                a21bt40vzccyt4
# 5 b001e4kfg0                                a3sgxh7auhu8gw, a1d87f6zcve5nk
# 6 b006k2zz7k a1uqrsclf8gw1t, adt0srk1mgoeu, a1sp2kvkfxxru1, a3jrgqveqn31iq


# ----------------------------------

### using dplyr and factor values
dt = data.frame(rpid, ruid, stringsAsFactors = T)

dt %>%
  group_by(rpid) %>%
  do(data.frame(list_ruids = paste(c(levels(dt$ruid)[.$ruid]), collapse=", "))) %>%
  ungroup

#         rpid                                                    list_ruids
#       (fctr)                                                         (chr)
# 1 b000e7l2r4                                                a1mzyo9tzk0bbi
# 2 b000lqoch0                                                 abxlmwjixxain
# 3 b000ua0qiq                                                a395borc6fgvxv
# 4 b00171apva                                                a21bt40vzccyt4
# 5 b001e4kfg0                                a3sgxh7auhu8gw, a1d87f6zcve5nk
# 6 b006k2zz7k a1uqrsclf8gw1t, adt0srk1mgoeu, a1sp2kvkfxxru1, a3jrgqveqn31iq


# -------------------------------------

library(data.table)

### using data.table
dt = data.table(rpid, ruid)

dt[, list(list_ruids = paste(c(ruid), collapse=", ")), by = rpid]

#          rpid                                                    list_ruids
# 1: b001e4kfg0                                a3sgxh7auhu8gw, a1d87f6zcve5nk
# 2: b000lqoch0                                                 abxlmwjixxain
# 3: b000ua0qiq                                                a395borc6fgvxv
# 4: b006k2zz7k a1uqrsclf8gw1t, adt0srk1mgoeu, a1sp2kvkfxxru1, a3jrgqveqn31iq
# 5: b000e7l2r4                                                a1mzyo9tzk0bbi
# 6: b00171apva                                                a21bt40vzccyt4