如何根据另一列中的特定日期和级别为列分配级别?

Posted

技术标签:

【中文标题】如何根据另一列中的特定日期和级别为列分配级别?【英文标题】:How to assign levels to a column based on specific dates and levels in another column? 【发布时间】:2020-02-21 00:37:13 【问题描述】:

我有一个包含 3 列的示例数据集:JulianDay、Device 和 location。请参阅下面的代码。

structure(list(JulianDay = 40:69, Device = structure(c(1L, 2L, 
3L, 1L, 2L, 3L, 1L, 2L, 3L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
2L, 3L, 1L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L), .Label = c("a", 
"b", "c"), class = "factor"), Location = c(1, 2, 3, 1, 2, 3, 
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 
1, 2, 3)), class = "data.frame", row.names = c(NA, -30L))

查看数据,可以看到设备 a 在第 40、43、46 天位于位置 1。但是设备更改位置,位置 1 在第 49、52、55 天被设备 b 和设备 c 占用在 61、64、67 上。所有三种设备都发生了类似的变化。

现在假设我们只有前两列,但我知道设备更改位置的每个日期以及它去往的位置。我怎么能用这些信息重建第 3 列。显然有 30 行,手动输入很容易,但我正在处理一个有几十万行的真实数据框。

编辑:

structure(list(JulianDay = c(40, 40, 40, 41, 41, 41, 42, 42, 
42, 43, 43, 43, 44, 44, 44, 45, 45, 45), Device = structure(c(1L, 
2L, 3L, 1L, 2L, 3L, 2L, 3L, 1L, 2L, 3L, 1L, 3L, 1L, 2L, 3L, 1L, 
2L), .Label = c("a", "b", "c"), class = "factor"), Location = c(1, 
2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)), class = "data.frame", row.names = c(NA, 
-18L))

这是一个类似的数据框,可以解决这个问题。每个设备每天都处于活动状态,并且每天都有 3 个位置。如果没有物理位置列(但知道应该包含什么),我想编写如下代码:

if(JulianDay < 41 & Device == 'A')  Location == 1
if(JulianDay > 41 * JulianDay < 44 & Device == 'A')  Location == 3
if(JulianDay > 44 & Device == 'A') Location == 2

这样填写第三列(位置)。

【问题讨论】:

这个问题我不清楚。你的意思是特定的一天总是与特定的位置相关联吗?例如,如果 40 为 1,则 41 为 2,42 为 3,43 为 1,依此类推。 @MikaelPoulJohannesson 刚刚编辑了帖子。希望这可以消除混乱。 【参考方案1】:

如果您有一组基于JulianDayDevice 的条件期望需要依次执行以创建Location,那么您应该看看dplyr::case_when

来自文档(参见?dplyr::case_when):

此函数允许您向量化多个“if_else()”语句。 它是 SQL ‘CASE WHEN’ 语句的 R 等价物。如果没有病例 匹配,返回“NA”。

例如,以你的例子,

data <- structure(list(JulianDay = c(40, 40, 40, 41, 41, 41, 42, 42, 
42, 43, 43, 43, 44, 44, 44, 45, 45, 45), Device = structure(c(1L, 
2L, 3L, 1L, 2L, 3L, 2L, 3L, 1L, 2L, 3L, 1L, 3L, 1L, 2L, 3L, 1L, 
2L), .Label = c("a", "b", "c"), class = "factor"), Location = c(1, 
2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3)), class = "data.frame", row.names = c(NA, 
-18L))

library(dplyr)

data$Location <- case_when(
  data$JulianDay < 41 & data$Device == "a" ~ 1,
  data$JulianDay > 41 & data$JulianDay < 44 & data$Device == "a" ~ 3,
  data$JulianDay > 44 & data$Device == "a" ~ 2
)

【讨论】:

以上是关于如何根据另一列中的特定日期和级别为列分配级别?的主要内容,如果未能解决你的问题,请参考以下文章

根据另一列中的更改创建带有时间戳的最后修改列

为列中的每个唯一值分配值[重复]

如何在 Presto 中获取连续日期,其中一列中的开始日期和另一列中的结束日期

SQL - 根据另一列中的日期过滤一列的结果

根据另一列中的元素重命名特定列元素

在数据框中创建列,按因子级别从另一列中采样