我有一个看起来像这样的数据框,只有更多的附加列,这对于这个问题并不重要。
DAY MONTH YEAR NAME SURNAME
1 1 1 2012 Luke Skywalker
2 3 4 2012 Luke Skywalker
3 3 4 2012 Luke Skywalker
4 1 8 2013 Han Solo
5 5 8 2013 Han Solo
6 5 8 2013 Han Solo
7 1 1 2012 Ben Solo
8 6 2 2011 Leia Organa
DAY
,MONTH
和YEAR
表示此人的出生日期。但由于缺少某些日期(但它们有多年),如果没有生日,则默认为DAY=1
和YEAR=1
。同一年份同一年内出现同一个名称不止一次。当然,有些人可能会在1.1.year
我想要做的是,搜索那些具有生日默认值并将其设置为正确的那些。
我做的是:我创建了一个子数据框,其中只包含那些行,1.1.year
在同一年只发生过一次相同的名称(如果它不止一次,我们可以假设这是他的出生日)和人数在哪里(在整个df中有多少同名,姓和年的人)大于1.如果不是,我们只有一行这个日期我们什么也说不出来。 (就像她Ben
)的情况一样。如果只有两次出现,一次是1.1.year,一次没有,那么非默认值(1.1)优先。
现在我计划迭代这个新的子数据框,匹配每个姓氏和年份,并用一个替换日期,这是该年名称中最常见的,但我不知道如何做到这一点有效率的。数据框很大,因此for
循环可能是不可能的。
我想要的是:
DAY MONTH YEAR NAME SURNAME
1 3 4 2012 Luke Skywalker
2 3 4 2012 Luke Skywalker
3 3 4 2012 Luke Skywalker
4 5 8 2013 Han Solo
5 5 8 2013 Han Solo
6 5 8 2013 Han Solo
7 1 1 2012 Ben Solo
8 6 2 2011 Leia Organa
答案 0 :(得分:2)
使用dplyr
的解决方案。请注意,当数据集中的流行率存在关联时,此代码不会处理这种情况。它假设记录中只有一个日期最丰富,并选择一条记录来替换不占优势的记录。
library(dplyr)
dt2 <- dt %>%
mutate(ID = 1:n()) %>%
group_by(NAME, SURNAME, DAY, MONTH, YEAR) %>%
mutate(N = n()) %>%
ungroup() %>%
group_by(NAME, SURNAME) %>%
mutate_at(vars(DAY, MONTH), funs(ifelse(N != max(N), NA, .))) %>%
arrange(DAY, MONTH) %>%
mutate_at(vars(DAY, MONTH), funs(ifelse(is.na(.), first(.), .))) %>%
arrange(ID) %>%
select(-N, -ID)
dt2
# A tibble: 8 x 5
# Groups: NAME, SURNAME [4]
DAY MONTH YEAR NAME SURNAME
<dbl> <dbl> <int> <chr> <chr>
1 3 4 2012 Luke Skywalker
2 3 4 2012 Luke Skywalker
3 3 4 2012 Luke Skywalker
4 5 8 2013 Han Solo
5 5 8 2013 Han Solo
6 5 8 2013 Han Solo
7 1 1 2012 Ben Solo
8 6 2 2011 Leia Organa
dt <- read.table(text = " DAY MONTH YEAR NAME SURNAME
1 1 1 2012 Luke Skywalker
2 3 4 2012 Luke Skywalker
3 3 4 2012 Luke Skywalker
4 1 8 2013 Han Solo
5 5 8 2013 Han Solo
6 5 8 2013 Han Solo
7 1 1 2012 Ben Solo
8 6 2 2011 Leia Organa",
header = TRUE, stringsAsFactors = FALSE)