【问题标题】:How do you replace missing values with 0 for cases meeting specific conditions in R?对于满足 R 中特定条件的情况,如何用 0 替换缺失值?
【发布时间】:2020-07-09 03:28:06
【问题描述】:

背景:

我正在处理一个包含 195,318 名参与者赌博行为纵向数据的大型数据集。该数据基于对赌博运营商内电子赌博行为的完整跟踪。赌博行为数据按月汇总,总计 70 个月。我有一个用于分隔参与者的 ID 变量、一个时间变量(月份),以及许多赌博行为变量,例如给定月份的活跃天数、给定月份的投注、给定月份的总损失等。参与者的时间不同一直在积极赌博。一位参与者可能在第 2、3、4 和 7 个月赌博,另一位参与者在 3、5 和 7 个月赌博,第三位参与者在 23、24、48、65 等等。因此,存在大量“缺失值” ”。但是,由于跟踪了每个赌博实例,因此该数据集中的缺失意味着该人没有赌博。也就是说,缺失等于0。

问题/目标:

我想将缺失值(“NA”)归为 0。 但是我只想在特定情况下这样做。具体来说,我想将我定义为参与者“活跃期”的缺失值归为 0,并保持其他所有内容不变。

参与者的活跃期是从他们第一个活跃的赌博月到最后一个月的赌博之间的每个月。例如,对于在第 2 个月、第 3 个月、第 4 个月和第 7 个月赌博的参与者,我想在第 5 个月和第 6 个月估算 0。每隔一个月,即 1 和 9 到 70,我想保持 NA。我正在努力编写实现这一目标的代码。我是 R 新手。

示例数据框和代码

以下是生成数据框的示例代码,该数据框说明了我的问题中描述的关键特征。在此代码中,只有 2 个参与者、1 个赌博行为变量和 10 个时间点(“波”)。我已经包含了“长格式”和“宽格式”的数据框,因为我不确定哪一个会最有帮助/信息量最大。时间变量包含在“长格式”中。我的实际数据集是长格式的,但我熟悉如何在两者之间切换。

# Example variables and data frame in long form
  # Includes id variable, time variable and example variable
id <- c(1, 1, 1, 1, 2, 2, 2)
time <- c(2, 3, 4, 7, 3, 5, 7)
daysPlayed <- c(2, 2, 3, 3, 2, 2, 2)
dfLong <- data.frame(id = id, time = time, daysPlayed = daysPlayed)

reprex package (v0.3.0) 于 2020 年 3 月 28 日创建

# Example variables and data frame in wide form
  # Includes id variable, days played in given month 
id <- c(1, 2)
daysPlayed.1 <- c(NA, NA)
daysPlayed.2 <- c(2, NA)
daysPlayed.3 <- c(2, 2)
daysPlayed.4 <- c(3, NA)
daysPlayed.5 <- c(NA, 2)
daysPlayed.6 <- c(NA, NA)
daysPlayed.7 <- c(3, 2)
daysPlayed.8 <- c(NA, NA)
daysPlayed.9 <- c(NA, NA)
daysPlayed.10 <- c(NA, NA)
dfWide <- data.frame(id=id, daysPlayed.1 = daysPlayed.1, daysPlayed.2 = daysPlayed.2,
                 daysPlayed.3 = daysPlayed.3, daysPlayed.4 = daysPlayed.4,
                 daysPlayed.5 = daysPlayed.5, daysPlayed.6 = daysPlayed.6,
                 daysPlayed.7 = daysPlayed.7, daysPlayed.8 = daysPlayed.8,
                 daysPlayed.9 = daysPlayed.9, daysPlayed.10 = daysPlayed.10)

reprex package (v0.3.0) 于 2020 年 3 月 28 日创建

【问题讨论】:

    标签: r if-statement conditional-statements missing-data


    【解决方案1】:

    对于这个例子,我们假设每个玩家 ie. id 将有 9 个月的数据(您可以稍后更改为实际月份值),我们可以使用 complete 来填充缺失的月份序列,并用介于两者之间的 0 填充该值。

    library(dplyr)
    
    dfLong %>%
      tidyr::complete(id, time = 1:9) %>%
      group_by(id) %>%
      mutate(daysPlayed = replace(daysPlayed, is.na(daysPlayed) & 
                          between(row_number(), min(which(!is.na(daysPlayed))),
                          max(which(!is.na(daysPlayed)))), 0))
    
    
    #     id  time daysPlayed
    #   <dbl> <dbl>      <dbl>
    # 1     1     1         NA
    # 2     1     2          2
    # 3     1     3          2
    # 4     1     4          3
    # 5     1     5          0
    # 6     1     6          0
    # 7     1     7          3
    # 8     1     8         NA
    # 9     1     9         NA
    #10     2     1         NA
    #11     2     2         NA
    #12     2     3          2
    #13     2     4          0
    #14     2     5          2
    #15     2     6          0
    #16     2     7          2
    #17     2     8         NA
    #18     2     9         NA
    

    如果我们想为每个ids 活动期间填充缺失的time,我们可以使用:

    dfLong %>%
      group_by(id) %>%
      tidyr::complete(time = seq(min(time), max(time)), fill = list(daysPlayed = 0))
    

    【讨论】:

    • 此代码有效,谢谢。但是,是否可以只为参与者的活跃期完成时间?我有 70 个时间点,并且为每个参与者的每个时间点添加行会使我的数据框膨胀(从大约 300 万到 1300 万个观察值)。例如,如果我的一位参与者在 2、3、4 和 7 处有测量值,我真的只需要它为该参与者添加 1、5 和 6 行。或者,如果有一些代码允许我删除仅是 NA 值的行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    • 2020-05-16
    • 2019-02-03
    • 2020-08-18
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    相关资源
    最近更新 更多