只查找r

时间:2017-03-01 09:18:39

标签: r

我坚持将个人成员定义为个人。我在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中是否有一个公式给我组成员?

3 个答案:

答案 0 :(得分:0)

我们可以使用combncSplit

执行此操作
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.tablecSplit

实施相同的功能
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))

答案 1 :(得分:0)

使用dplyrtidyr,您可以通过以下方式解决此问题。首先,我们定义一个解决单个组问题的函数,然后我们只需使用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

答案 2 :(得分:0)

另一个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)))