我一直在为个人定义小组成员。我在excel工作,但这是失败的,因为一个群体中的个人数量在不同的组之间有所不同。我用了这个公式
=IFERROR(INDEX($A$1:$A$10727;SMALL(IF($S$1:$S$10727=$S2;ROW($S$1:$S$10727);"");Nth);1);"NA")这将返回组中的第N个个体。这是不可行的,因为给我所有的个人,我只想要小组成员,而不是个人本身。所以我想去R,但我不知道从哪里开始。
我的数据如下:
group ID
1 1
1 2
1 3
2 4
2 5
3 6
3 7
3 8
3 9
3 10我想这样做:
group ID gm1 gm2 gm3 gm4
1 1 2 3 NA NA
1 2 1 3 NA NA
1 3 1 2 NA NA
2 4 5 NA NA NA
2 5 4 NA NA NA
3 6 7 8 9 10
3 7 6 8 9 10
3 8 6 7 9 10
3 9 6 7 8 10
3 10 6 7 8 9在R中有给我小组成员的公式吗?
发布于 2017-03-01 09:35:02
我们可以用combn和cSplit来完成这个任务。
library(splitstackshape)
df1$gm <- unlist(unsplit(lapply(split(df1$ID, df1$group), function(x)
lapply(x, function(y) {
i1 <- x[y!= x]
if(length(i1) >1) combn(i1, length(i1), FUN = paste, collapse=", ") else i1
})), df1$group))
cSplit(df1, 'gm', ', ')
# group ID gm_1 gm_2 gm_3 gm_4
# 1: 1 1 2 3 NA NA
# 2: 1 2 1 3 NA NA
# 3: 1 3 1 2 NA NA
# 4: 2 4 5 NA NA NA
# 5: 2 5 4 NA NA NA
# 6: 3 6 7 8 9 10
# 7: 3 7 6 8 9 10
# 8: 3 8 6 7 9 10
# 9: 3 9 6 7 8 10
#10: 3 10 6 7 8 9也可以用data.table和cSplit来实现。
library(data.table)
cSplit(setDT(df1)[, gm := unlist(lapply(seq_len(.N), function(i) {
i1 <- ID[i != seq_len(.N)]
if(length(i1) > 1) combn(i1, length(i1), FUN =paste, collapse=", ")
else as.character(i1)})), group], 'gm', ', ')数据
df1 <- structure(list(group = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 3L,
3L), ID = 1:10), .Names = c("group", "ID"), class = "data.frame", row.names = c(NA,
-10L))发布于 2017-03-01 09:56:32
使用dplyr和tidyr,您可以通过以下方式解决这个问题。首先我们定义一个函数来解决单个组的问题,然后简单地使用do将该函数应用于所有组。
library(dplyr)
df <- data.frame(group = rep(1:3, c(3, 2, 5)), ID = 1:10)
add_group_members <- function(df) {
df_copy <- df
colnames(df_copy)[2] <- "gm_id"
inner_join(df, df_copy, by = c("group" = "group")) %>%
filter(ID != gm_id) %>%
group_by(ID) %>%
mutate(gm = paste("gm", row_number(), sep = '')) %>%
tidyr::spread(key = gm, value = gm_id) %>% ungroup
}
df %>% group_by(group) %>% do(add_group_members(.)) %>% ungroup发布于 2017-03-01 10:13:28
另一个tidyverse解决方案:
df <- data.frame(x = rep(1:3, c(3, 2, 5)), id = 1:10)
library(tidyverse)
df2 <-
df %>%
group_by(x) %>%
mutate(unique = paste(unique(id), collapse = ","))
df2$group_unique <- map_chr(seq_len(nrow(df2)), function(index) {
row_unique <- as.numeric(strsplit(df2[[index, "unique"]], ",")[[1]])
paste0(setdiff(row_unique, df2[[index, "id"]]), collapse = ",")
})
df2 %>%
select(-unique) %>%
separate(group_unique, paste("gm_", 1:(max(table(df$x)) - 1)))https://stackoverflow.com/questions/42527731
复制相似问题