R Groupby by列返回多列中的唯一值

时间:2017-05-22 14:46:25

标签: 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

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

3 个答案:

答案 0 :(得分:1)

您可以使用bind_rows中的dplyr快速轻松地将数据框转换为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

答案 1 :(得分:1)

Heres是使用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

答案 2 :(得分:0)

我相信使用dplyrtidyr您可以执行gather操作,将两个id列合二为一。像

这样的操作
df %>%
  group_by(clustid) %>%
  gather(idtype, uniqueID, sourceID, targetID) %>%
  arrange(uniqueID) %>%
  unique() %>%
  select(clustid, uniqueID) %>%
  ungroup()

应该做的伎俩。