如何在 R 延续的数据框中将第一个唯一记录标记(标记)为 1,其余类似记录为 0

Posted

技术标签:

【中文标题】如何在 R 延续的数据框中将第一个唯一记录标记(标记)为 1,其余类似记录为 0【英文标题】:How can I mark (flag) first unique record as 1 and the rest similar records as 0 in data frame in R continuation 【发布时间】:2021-08-06 12:00:48 【问题描述】:

我在 R 和 dplyr 中的数据方面需要帮助。 我的第一个问题在这里解决了:How can I mark (flag) first unique record as 1 and the rest similar records as 0 in data frame in R 但我需要改进这些数据。我使用如下代码:

df %>% mutate(drive = +!duplicated(paste(date, adress)))

结果如下:

 jobs, date, adress, drive 
1 111 28.03    bla     1 
2 111 28.03    bla     0 
3 111 28.03    bla     0 
4 111 28.03    bla     0 
5 111 28.03    bla     0 
6 111 28.03    bla     0 
7 111 28.03    bla     0 
8 111 28.03    bla     0 
9 111 28.03    bla     0 <- 9th record of the same job
10 111 28.03    bla     0 <- 10th record of the same job
11 345 05.03    bla     1 
12 111 28.03    bla     0  
13 236 28.03    abc     1

我需要改进一下我的 dplyr,我的数据应该是这样的:

 jobs, date, adress, drive 
1 111 28.03    bla     1 
2 111 28.03    bla     0 
3 111 28.03    bla     0 
4 111 28.03    bla     0 
5 111 28.03    bla     0 
6 111 28.03    bla     0 
7 111 28.03    bla     0 
8 111 28.03    bla     0 
9 111 28.03    bla     0 <- 9th record of the same job
10 111 28.03    bla     1 <- 10th record, it should be 1 not 0. Sum of "the same jobs" above 9 give me again flag 1.
11 345 05.03    bla     1 <- new record of the job, so 1
12 111 28.03    bla     0
13 236 28.03    abc     1 

所以,第一个记录给我 1,同一份工作的第 2-9 条记录给我 0,同一工作的第 10 条记录给我再给我 1,第 11-19 条记录给我 0 等等。

【问题讨论】:

您的意思是第 1、第 10 和第 10 条记录的其他倍数要标记为 1? 是的,没错。记录 1、10 和 20 等。 但是您的样本数据不包含任何“工作”值?你的意思是date改变是一份新工作吗? 好的,我在上面编辑了一点我的数据。 是的,我的工作类似于工作/商家 ID。因此我们可以按工作 ID(可选地址)和日期进行分组。如果我们有其他日期,但工作 ID 相同,请重新开始计数。 【参考方案1】:

当有多个条件要测试时,我喜欢使用case_when 而不是嵌套的if_elses。它通过按顺序运行每个测试并在第一个 TRUE 测试的~ 之后输出部分来工作。我在这里的最后一个测试只是TRUE,所以前两个测试中没有发现的任何东西都会产生一个0。

df %>%
  group_by(date, adress) %>%   # do these two vars define each "job"? 
  mutate(drive = case_when(
    row_number() == 1 ~ 1,
    row_number() %% 10 == 0 ~ 1,
    TRUE ~ 0)) %>%
  ungroup()

由于只有两个输出值,因此可以交替编码为

df %>%
  group_by(date, adress) %>%   # do these two vars define each "job"? 
  mutate(drive = if_else(row_number() == 1 | row_number() %% 10 == 0, 1, 0)) %>%
  ungroup()

【讨论】:

【参考方案2】:

基础 r 方法

df <- structure(list(jobs = c(111L, 111L, 111L, 111L, 111L, 111L, 111L, 
                              111L, 111L, 111L, 345L, 111L, 236L), date = c("28.03", "28.03", 
                                                                            "28.03", "28.03", "28.03", "28.03", "28.03", "28.03", "28.03", 
                                                                            "28.03", "5.03", "28.03", "28.03"), adress = c("bla", "bla", 
                                                                                                                           "bla", "bla", "bla", "bla", "bla", "bla", "bla", "bla", "bla", 
                                                                                                                           "bla", "abc")), row.names = c("1", "2", "3", "4", "5", "6", "7", 
                                                                                                                                                         "8", "9", "10", "11", "12", "13"), class = "data.frame")

transform(df, drive = ave(df$jobs, paste(df$jobs, df$date), FUN = function(x) +(seq_len(length(x)) == 1 | seq_len(length(x)) %% 10 == 0)))
#>    jobs  date adress drive
#> 1   111 28.03    bla     1
#> 2   111 28.03    bla     0
#> 3   111 28.03    bla     0
#> 4   111 28.03    bla     0
#> 5   111 28.03    bla     0
#> 6   111 28.03    bla     0
#> 7   111 28.03    bla     0
#> 8   111 28.03    bla     0
#> 9   111 28.03    bla     0
#> 10  111 28.03    bla     1
#> 11  345  5.03    bla     1
#> 12  111 28.03    bla     0
#> 13  236 28.03    abc     1

由reprex package (v2.0.0) 于 2021-05-19 创建


dplyr 接近

library(dplyr)

df %>% group_by(jobs, date) %>%
  mutate(drive = +(as.numeric(row_number()) == 1 | as.numeric(row_number()) %% 10 == 0))
#> # A tibble: 13 x 4
#> # Groups:   jobs, date [3]
#>     jobs date  adress drive
#>    <int> <chr> <chr>  <dbl>
#>  1   111 28.03 bla        1
#>  2   111 28.03 bla        0
#>  3   111 28.03 bla        0
#>  4   111 28.03 bla        0
#>  5   111 28.03 bla        0
#>  6   111 28.03 bla        0
#>  7   111 28.03 bla        0
#>  8   111 28.03 bla        0
#>  9   111 28.03 bla        0
#> 10   111 28.03 bla        1
#> 11   345 5.03  bla        1
#> 12   111 28.03 bla        0
#> 13   236 28.03 abc        1

由reprex package (v2.0.0) 于 2021-05-19 创建

【讨论】:

好的,谢谢兄弟!我正在使用 dplyr,所以这个解决方案更接近我。 :) 有效!这个带有“case_when”的解决方案也不错。

以上是关于如何在 R 延续的数据框中将第一个唯一记录标记(标记)为 1,其余类似记录为 0的主要内容,如果未能解决你的问题,请参考以下文章

根据唯一值标记数据框

如何在熊猫中将一组行混在一起(行具有唯一的ID)

识别和标记R中的部分重复记录

在 R 中,当 ID 不唯一时,如何从每个 ID 的数据框中获取倒数第二行? [复制]

如何在组合框中将第一个索引设置为空白

如何从 R 数据框中过滤列的唯一组合