【问题标题】:How to check if NA within replace() function in R?如何检查 R 中的 replace() 函数中是否存在 NA?
【发布时间】:2020-06-01 11:29:41
【问题描述】:

在我的数据集中,活动的持续时间以小时(duration_hours 列)或分钟(duration_minutes 列)为单位。如果以小时为单位,duration_minutes 列为空 (NA),反之亦然。
我现在想通过将分钟数除以 60(分钟)将其转换为小时数。

为此,我尝试了以下命令:

df <- df %>% mutate(duration_recoded = replace(duration_minutes, !is.na(duration_minutes), duration_minutes / 60))

但是,该命令会产生不正确的结果并显示以下警告消息:

Warning message:
In x[list] <- values :
  number of items to replace is not a multiple of replacement length

谁能告诉我我的错误在哪里?

以下是一些示例数据:

df <- structure(list(duration_hours = c(1, NA, 2, NA, 1), duration_minutes = c(NA, 25, NA, 30, NA)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", "data.frame"))

【问题讨论】:

标签: r dplyr


【解决方案1】:

我们可以在这里使用dplyr 包中的coalesce() 函数:

library(dplyr)
df <- df %>% mutate(duration_recoded = coalesce(duration_hours, duration_minutes / 60))

这应该有效,因为如果duration_hours 不是NA,那么coalesce 会简单地抓取它并将其分配给duration_recorded。如果duration_hours 实际上是NA,那么它将通过,取而代之的是duration_minutes 除以60。

【讨论】:

  • 这是一个非常优雅的解决方案。非常感谢!但是,这真的会帮助我理解我的方法有什么问题。我觉得这与建议的内容没有什么不同,例如这里stackoverflow.com/a/28013895/12912548
  • @mpds 您当前方法的问题是,如果持续时间字段为空,您只想替换为持续时间分钟除以 60。
  • 但是这不是和例子中的基本一样,当值为4时,值改变了?换种方式问,问题是 !is.na(duration_minutes) 还是命令的 duration_minutes / 60 部分?
  • 不,你对replace()的用法/理解是错误的,逻辑肯定是错误的,因为你需要检查duration_hours的存在,然后再决定替换什么。跨度>
  • 这不是我的代码所做的(至少我试图让它做的)?首先它检查duration_hours是否不为空,然后才用它自己的值除以60来替换它。
【解决方案2】:

您的代码中的问题是持续时间分钟是一个向量,当您除以 60 时,您正在执行向量运算。让我们用一个例子df:

# A tibble: 7 x 1
  duration_minutes
             <dbl>
1               10
2               20
3               30
4               NA
5               50
6               NA
7               60

在这种情况下,df$duraction_minutes / 60 会导致:

0.1666667 0.3333333 0.5000000        NA 0.8333333        NA 1.0000000

这意味着您正在尝试用多个值的向量替换每个 NA 值...这就是您的警告消息显示number of items to replace is not a multiple of replacement length 的原因。

您要么必须使用将多个值聚合为单个值的函数(例如sum()mean()first() 等),要么必须选择单个值作为替换值。 coalesce() 函数只是找到第一个非缺失元素。

【讨论】:

  • 如果我的代码产生了您帖子中给出的值,那么一切都会好起来的。但是,如果您尝试我的示例数据,则有两行具有 duration_minutes 的值,因此应该重新编码。第一个非 NA 元素 (25) 被代码忽略,第二个 (30) 重新编码不正确(值为 0.416 而不是 0.5)。
猜你喜欢
  • 1970-01-01
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
  • 2012-04-10
  • 2010-11-05
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
相关资源
最近更新 更多