R 按列分组以返回多列中的唯一值

  • 本文关键字:唯一 返回 r dataframe grouping
  • 更新时间 :
  • 英文 :


这很可能是重复的 - 让我知道,我会删除。

我有一些数据帧:

   from   to  value sourceID targetID clustid
1  1400 1413 0.6846  3055586  3060697       1
2   323  661 0.5550  1596205   724084       1
3   323 1411 0.6817   724084  3060607       1
4  1413 1411 0.6729  3060697  3060607       1
5  1498 1411 0.6381  3111960  3060607       1
6  1478 1415 0.7423  3062164  3099199       2
7  1478 1414 0.7423  3099199  3062163       2
8  1415 1462 0.7078  3090708  3062164       2
9  1415 1463 0.7078  3062164  3090709       2
10 1462 1404 0.7078  3090708  3058341       2

我想执行一个等效于 Python Pandas groupby() 函数,根据clustid对我的数据进行分组。

此外,我还想返回一个包含 sourceIDtargetID 唯一值的新数据帧,并对这些值进行排序。这样,我的输出将是:

 UniqueID
1 724084
  1596205
  3055586
  3060607
  3060697
  3111960
2 3058341
  3062163
  3062164
  3090708
  3090709
  3099199

我知道我可以使用unique()返回sourceIDtargetID列所有行的唯一 ID 列表,如下所示:

unique_ids <- sort(unique(c((df$sourceID), (df$targetID))))
> unique_ids
 [1]  370871  370873  374920  431814  612944  724084 1145838 1145839 1312582 1365467 1365468 1450552 1450553 1469099 1477137 1519842 1528881 1596205 1919812 1935866
[21] 2933725 2933726 3018082 3055586 3058341 3060607 3060697 3062163 3062164 3064884 3064885 3083388 3090708 3090709 3099199 3111960 3458397

但是,如何仅针对特定clustid并将结果存储为上面的数据帧呢?

非常感谢您的帮助。

@Sotos建议让我:

lapply(split(df, df$clustid), function(i) sort(unique(c(i$sourceID, i$targetID))))
$`1`
[1]  724084 1596205 3055586 3060607 3060697 3111960
$`2`
[1] 3058341 3062163 3062164 3090708 3090709 3099199
$`3`
[1]  612944 1919812 1935866 3018082 3064884 3064885
$`4`
[1] 1312582 1365467 1365468 2933725 2933726 3083388 3458397
$`5`
[1] 1450552 1450553 1469099 1477137 1519842 1528881
$`6`
[1]  370871  370873  374920  431814 1145838 1145839

不幸的是,这不是我所追求的。

这是

使用data.table包的解决方案。假设您的表存储在名为 df 的数据框中。

df <- data.table(df)
df <- df[, list(id = unique(c(targetID, sourceID))), by = clustid]
setkeyv(df, c("clustid", "id"))

然后df的内容是

##     clustid      id
##  1:       1  724084
##  2:       1 1596205
##  3:       1 3055586
##  4:       1 3060607
##  5:       1 3060697
##  6:       1 3111960
##  7:       2 3058341
##  8:       2 3062163
##  9:       2 3062164
## 10:       2 3090708
## 11:       2 3090709
## 12:       2 3099199

您可以使用dplyr中的bind_rows快速轻松地转换为数据框以及ID,即

dplyr::bind_rows(lapply(split(df, df$clustid), 
                 function(i)data.frame(IDs = sort(unique(c(i$sourceID, i$targetID))))), 
                                                                          .id = 'cluster')
#   cluster     IDs
#1        1  724084
#2        1 1596205
#3        1 3055586
#4        1 3060607
#5        1 3060697
#6        1 3111960
#7        2 3058341
#8        2 3062163
#9        2 3062164
#10       2 3090708
#11       2 3090709
#12       2 3099199
我相信

使用 dplyrtidyr 您可以执行gather操作将两个 id 列合二为一。像这样的操作

df %>%
  group_by(clustid) %>%
  gather(idtype, uniqueID, sourceID, targetID) %>%
  arrange(uniqueID) %>%
  unique() %>%
  select(clustid, uniqueID) %>%
  ungroup()

应该做这个伎俩。

最新更新