【问题标题】:Identifying missing observations in groups识别组中缺失的观察结果
【发布时间】:2019-09-27 12:14:20
【问题描述】:

我的代码有一些困难,希望你们中的一些人能提供帮助。

数据集如下所示:

df <- data.frame("group" = c("A", "A", "A","A_1", "A_1", "B","B","B_1"), 
                 "id" = c("id1", "id2", "id3", "id2", "id3", "id5","id1","id1"), 
                 "time" = c(1,1,1,3,3,2,2,5),
                 "Val" = c(10,10,10,10,10,12,12,12))

“group”表示个人“id”所在的组。“A_1”表示一个主题已离开该组。

例如,一个主题“id1”离开“组 A”,成为组“A_1”,其中只有“id2”和“id3”是成员。同样,“id5”离开组 B,成为“B_1”,只有 id1 作为成员。

我希望在最终数据集中拥有相反类型的组标识,应该如下所示:

final <- data.frame("group" = c("A", "A", "A","A_1", "B","B","B_1"), 
                     "id" = c("id1", "id2", "id3", "id1", "id5","id1","id5"), 
                     "time" = c(1,1,1,3,2,2,5),
                     "Val" = c(10,10,10,10,12,12,12),
                     "groupid" = c("A", "A", "A","A", "B","B","B"))

其中“A_1”和“B_1”仅表示已离开原组的科目,分别为“id1”和“id5”,而不是标识剩余科目。

有人对我如何系统地做到这一点有建议吗?

提前感谢您的帮助。


跟进:

我的数据比上面的例子稍微复杂一些,因为治疗有多个“出口”,而且组标识符可以具有不同的字符长度(例如 AAA 和 B)。数据看起来更像如下:

df2 <- data.frame("group" = c("AAA", "AAA", "AAA","AAA","AAA_1","AAA_1", "AAA_1","AAA_2","AAA_2","B","B","B_1"), 
                  "id" = c("id1", "id2", "id3","id4", "id2", "id3","id4", "id2","id3", "id5","id1","id1"), 
                  "time" = c(1,1,1,1,3,3,3,6,6,2,2,5),
                  "Val" = c(10,10,10,10,10,10,10,10,10,12,12,12))

id1 在时间 3 离开组 AAA,成为组 AAA_1,而在时间 6,id4 也离开组 AAA,成为组 AAA_2。如前所述,我希望带有“_”的组来标识离开该组的那些 id,而不是剩下的那个。因此最终的数据集应该是这样的:

final2 <- data.frame("group" = c("A", "A", "A","A","A_1","A_2",                     
                              "B","B","B_1"), 
                  "id" = c("id1", "id2", "id3","id4", "id1", "id4", "id5","id1","id5"), 
                  "time" = c(1,1,1,1,3,6,2,2,5),
                  "Val" = c(10,10,10,10,10,10,12,12,12))

谢谢你帮我解决这个问题

【问题讨论】:

  • 你能提供更多关于groupid的细节吗?
  • 确定什么样的细节?基本上,该组的成员接受“Val”治疗。我感兴趣的是明确区分那些停止接受治疗的受试者,因此那些退出该组的受试者。然而,构建数据集以指示继续接受治疗的受试者。因此,我想找到一种“反转”组标识的方法,以便“A_1”和“A_2”表示停止接受治疗的受试者
  • 请注意,在一个小组中,多个人可以在不同的时间停止接受治疗。因此“A_1”和“A_2”可以存在,其中“id1”、“id2”在不同时间停止接受治疗。理想情况下,这应该反映在我的新数据中
  • 对不起,我不明白你在做什么
  • 对不起,我可能没有很好地解释自己。抽象的很简单。我会再尝试。基本上,带有“_”符号的组是一个人离开该组的组。例如,在我的示例中,“B_1”是 id5 离开的组。我想要实现的是一个分类,我的观察是 id5,“B_1”。但是,在当前数据集中,观察“B_1”与留在组中的个体相关联,即观察是 B_1,id1(即留在组中的个体)。我正在尝试找到一种方法来系统地重新排列此分类。

标签: r data-manipulation


【解决方案1】:

好的,你可以用这种方式尝试dplyr:也许它不优雅,但你得到了结果。背后的想法是首先获取group ... 中但不在相对..._1 中的那些,然后更改它们的group,获取其他的和rbind 一起:

library(dplyr)
# first you could find the one that are missing in the ..._1 groups
# and change their group to ..._1
    dups <-
           df %>%
           group_by(id, groupid = substr(group,1,1)) %>%
           filter(n() == 1)%>%
           mutate(group = paste0(group,'_1')) %>%
           left_join(df %>%
                     select(group, time, Val) %>%
                     distinct(), by ='group') %>% 
           select(group, id, time = time.y, Val = Val.y) %>%
           ungroup()

dups
# A tibble: 2 x 5
  groupid group id     time   Val
  <chr>   <chr> <fct> <dbl> <dbl>
1 A       A_1   id1       3    10
2 B       B_1   id5       5    12

# now you can select the ones that are in both groups:
dups2 <-
        df %>%
        filter(nchar(as.character(group)) == 1) %>%
        mutate(groupid = substr(group,1,1))

   dups2
  group  id time Val groupid
1     A id1    1  10       A
2     A id2    1  10       A
3     A id3    1  10       A
4     B id5    2  12       B
5     B id1    2  12       B

最后,rbind() 他们,arrange() 他们和order() 列:

rbind(dups, dups2) %>%
 arrange(group) %>%
 select(group, id, time, Val, groupid)

# A tibble: 7 x 5
  group id     time   Val groupid
  <chr> <fct> <dbl> <dbl> <chr>  
1 A     id1       1    10 A      
2 A     id2       1    10 A      
3 A     id3       1    10 A      
4 A_1   id1       3    10 A      
5 B     id5       2    12 B      
6 B     id1       2    12 B      
7 B_1   id5       5    12 B 

希望对你有帮助!


编辑:

您可以通过一些工作对其进行概括,这是我的尝试,希望对您有所帮助:

library(dplyr)
df3 <- df2

# you have to set a couple of fields you need:
df3$group <-ifelse(
  substr(df2$group,(nchar(as.character(df2$group))+1)-1,nchar(as.character(df2$group))) %in% c(0:9),
  paste0(substr(df2$group,1,1),"_",substr(df2$group,(nchar(as.character(df2$group))+1)-1,nchar(as.character(df2$group)))),
  paste0(substr(df2$group,1,1),"_0")
  )

df3$util <- as.numeric(substr(df3$group,3,3))+1

# two empty lists to populate with a nested loop:
changed <- list()
final_changed <- list()

现在先找谁变了,然后另一个:思路和上一部分一样:

for (j in c("A","B")) {
 df3_ <- df3[substr(df3$group,1,1)==j,] 
 for (i in unique(df3_$util)[1:length(unique(df3_$util))-1]) {
       temp1 <- df3_[df3_$util == i,]
       temp2 <- df3_[df3_$util == i+1,]
       changes <- temp1[!temp1$id %in% temp2$id,]
       changes$group <- paste0(j,'_',i )
       changes <- changes %>% left_join(temp2, by = 'group') %>% 
                  select(group , id = id.x, time = time.y, Val = Val.y)

     changed[[i]] <- changes
     }
  final_changed[[j]] <- changed
  }

change <- do.call(rbind,(do.call(Map, c(f = rbind, final_changed)))) %>% distinct()
change
  group  id time Val
1   A_1 id1    3  10
2   B_1 id5    5  12
3   A_2 id4    6  10

然后剩下的,拼凑起来:

remain <-
  df3 %>% mutate(group = gsub("_0", "", .$group)) %>%
  filter(nchar(as.character(group)) == 1) %>% select(-util)


rbind(change, remain) %>%
  mutate(groupid = substr(group,1,1)) %>% arrange(group) %>%
  select(group, id, time, Val, groupid)

  group  id time Val groupid
1     A id1    1  10       A
2     A id2    1  10       A
3     A id3    1  10       A
4     A id4    1  10       A
5   A_1 id1    3  10       A
6   A_2 id4    6  10       A
7     B id5    2  12       B
8     B id1    2  12       B
9   B_1 id5    5  12       B

【讨论】:

  • 感谢您的帮助,我在数据集中运行此代码时遇到了一些问题,因为组中有多个提款,(基本上有“A_1”、“A_2”等...)子组,难道这是造成问题的原因?
  • 是的,当然,在你的例子中只有两种组,所以我假设:你能提供一个数据集和一个包含两种以上组的解释吗?
  • @Alessandro 抱歉耽搁了,这里尝试更一般的示例,希望对您有所帮助:查看编辑。
猜你喜欢
  • 2019-08-19
  • 2015-04-10
  • 2018-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-13
  • 2021-08-19
  • 1970-01-01
相关资源
最近更新 更多