【问题标题】:Deleting rows w. duplicate information while keeping first non-duplicated entry (and appending that row with data from duplicate entries)删除行 w。重复信息,同时保留第一个非重复条目(并在该行附加来自重复条目的数据)
【发布时间】:2015-06-26 07:03:53
【问题描述】:

我有一个包含 500k 个条目(行)的数据集。每个条目都是针对特定学生的,并包含学生所在学校的信息 去了那个特定的学期。

因为学生在同一所学校呆了几个学期,所以我为同一学生和同一所学校有很多条目 (只有学期改变,即 EnrollmentBegin 和 EnrollmentEnd)。

FirstName LastName CollegeName State PublicPrivate EnrollmentBegin EnrollmentEnd
John      Doe    School A      NY       Public         20050829      20051223
John      Doe    School A      NY       Public         20051229      20060113
John      Doe    School A      NY       Public         20051223      20060513
John      Doe    School B      IL       Private        20090105      20090301
John      Doe    School B      IL       Private        20090706      20090830
John      Doe    School B      IL       Private        20090831      20091025
Jane      Doe    School A      IL       Private        20100105      20100301
Jane      Doe    School A      IL       Private        20100706      20100830
Jane      Doe    School A      IL       Private        20100831      20101025
John      Doe    School A      NY       Public         20110829      20111223
John      Doe    School A      NY       Public         20120129      20120513

这意味着对于某些学生,我有很多学生姓名和学院名称相同的条目。

我真的只想要每个新条目的第一个实例(即每当给定学生的学校名称更改时) 但我还需要知道学生在那所学校的入学时间是什么时候结束的。

此信息可在给定学校的每个学生的最后一个条目中找到。 因此,我需要从最后一个条目中获取该值,并将该值添加到该行中的新列,其中包含学生的第一个条目。

注意:我意识到有些学生,比如上面的 John Doe,去 A 学校,去另一所学校,然后回到 A 学校。因此,理想情况下,要捕捉 那,我希望我的最终数据集看起来像这样:

FirstName LastName CollegeName State PublicPrivate EnrollmentBegin EnrollmentEnd EnrollmentEnd
John      Doe    School A      NY       Public      20050829      20051223      20060513
John      Doe    School A      NY       Public      20110829      20111223      20120513
John      Doe    School B      IL       Private     20090105      20090301      20091025
Jane      Doe    School A      IL       Private     20100105      20100301      20101025

如何以最有效的方式做到这一点?好像 min 和 max 已经不能解决这个问题了……

【问题讨论】:

  • 嘿阿克伦。不,我只是想让这些值加粗,但我想我仍然没有完全掌握格式。
  • 看起来像简单的按最小最大分组练习。

标签: r dataframe duplicate-removal


【解决方案1】:

试试

library(data.table)
setDT(df1)[,list(EnrollmentBegin= EnrollmentBegin[1L], 
                   EnrollmentEnd=EnrollmentEnd[1L], 
                   EnrollmentEnd2= EnrollmentEnd[.N]) ,
   by =c(names(df1)[1:5])]
#   FirstName LastName CollegeName State PublicPrivate EnrollmentBegin
#1:      John      Doe    School A    NY        Public        20050829
#2:      John      Doe    School B    IL       Private        20090105
#3:      Jane      Doe    School A    IL       Private        20100105
#   EnrollmentEnd EnrollmentEnd2
#1:      20051223       20060513
#2:      20090301       20091025
#3:      20100301       20101025

或使用dplyr

library(dplyr)
df1 %>%
  group_by_(.dots=names(df1)[1:5]) %>% 
  summarise(EnrollmentBegin=EnrollmentBegin[1L], 
            EnrollmentEnd1=EnrollmentEnd[1L],
            EnrollmentEnd2 = EnrollmentEnd[n()]) 

【讨论】:

  • 完成了这项工作。我在考虑循环,但你只是在那里为我节省了一些时间。谢谢!
【解决方案2】:

使用基本 R 的替代方法lapply

lst = unname(split(dat, dat[,1:5])[lapply(split(dat, dat[,1:5]), nrow) != 0])
out = do.call(rbind, lapply(lst, 
              function(x){x$EnrollmentEnd.new = x$EnrollmentEnd[nrow(x)]; x[1,]}))

#> out
#  FirstName LastName CollegeName State PublicPrivate EnrollmentBegin
#7      Jane      Doe    School_A    IL       Private        20100105
#4      John      Doe    School_B    IL       Private        20090105
#3      John      Doe    School_A    NY        Public        20050829
#  EnrollmentEnd EnrollmentEnd.new
#7      20100301          20101025
#4      20090301          20091025
#3      20051223          20060513

【讨论】:

  • 另一个选项是by
  • 当我尝试使用 unname 命令时,我收到消息:“错误:无法分配大小为 129.4 Gb 的向量”并且只有 500 行。为什么这似乎是个问题?
  • @WykoW 不太确定,但我想这可能是因为拆分后有多个空列表元素。感谢您指出。我会尽快解决这个问题
猜你喜欢
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2019-11-20
  • 2023-01-11
  • 1970-01-01
  • 1970-01-01
  • 2014-04-15
相关资源
最近更新 更多