【问题标题】:Conditional value filtering条件值过滤
【发布时间】:2018-10-05 12:57:02
【问题描述】:

样本数据

library(dplyr)
df <- data.frame(
  ID = c(1,1,1,1,2,2,2,3,3,3),
  day = c(3,8,14,29,4,6,8,1,4,9),
  value = c(75, 101, 115, 120, 110, 106, 122, 100, 128, 140))

问题背后的想法:

为每个ID主题选择最小的day并将value特征乘以1.3(ID 1 - day 3 - value 75, ID 2 - 第 4 天 - 值 110,ID 3 - 第 1 天 - 值 100)。 然后将该新创建的 value 与具有相同 ID 但具有不同 day 编号的其他 value 进行比较。

例如:

ID 1 的最小 day 数字是 3。然后将该行的 乘以 1.3 (75 * 1.3 = 97.5) .将新创建的 value (97.5) 与具有相同 ID 1 的 values ((101, 115, 120)) 进行比较。然后anwser 如果新值大于 values ((101, 115, 120)),则返回 TRUE 或 FALSE。

ID 2 和 3 也重复此操作。

【问题讨论】:

  • 到目前为止您尝试过什么?请分享您的代码...

标签: r dataframe dplyr data-manipulation


【解决方案1】:
library(dplyr)

df <- data.frame(
  ID = c(1,1,1,1,2,2,2,3,3,3),
  day = c(3,8,14,29,4,6,8,1,4,9),
  value = c(75, 101, 115, 120, 110, 106, 122, 100, 128, 140))

df %>%
  group_by(ID) %>%
  mutate(v = value[day == min(day)] * 1.3,
         flag = value > v) %>%
  ungroup()

# # A tibble: 10 x 5
#      ID   day value     v flag 
#   <dbl> <dbl> <dbl> <dbl> <lgl>
# 1     1     3    75  97.5 FALSE
# 2     1     8   101  97.5 TRUE 
# 3     1    14   115  97.5 TRUE 
# 4     1    29   120  97.5 TRUE 
# 5     2     4   110 143   FALSE
# 6     2     6   106 143   FALSE
# 7     2     8   122 143   FALSE
# 8     3     1   100 130   FALSE
# 9     3     4   128 130   FALSE
#10     3     9   140 130   TRUE 

如果您想用至少一个TRUE flag 标记IDs,您可以像这样创建flag2

 df %>%
  group_by(ID) %>%
  mutate(v = value[day == min(day)] * 1.3,
         flag = value > v,
         flag2 = max(flag)) %>%
  ungroup()

# # A tibble: 10 x 6
#      ID   day value     v flag  flag2
#   <dbl> <dbl> <dbl> <dbl> <lgl> <int>
# 1     1     3    75  97.5 FALSE     1
# 2     1     8   101  97.5 TRUE      1
# 3     1    14   115  97.5 TRUE      1
# 4     1    29   120  97.5 TRUE      1
# 5     2     4   110 143   FALSE     0
# 6     2     6   106 143   FALSE     0
# 7     2     8   122 143   FALSE     0
# 8     3     1   100 130   FALSE     1
# 9     3     4   128 130   FALSE     1
#10     3     9   140 130   TRUE      1

或将IDs 提取为向量:

df %>%
  group_by(ID) %>%
  mutate(v = value[day == min(day)] * 1.3,
         flag = value > v) %>%
  ungroup() -> df2

df2 %>% 
  filter(flag == TRUE) %>%
  distinct(ID) %>%
  pull(ID)

#[1] 1 3

【讨论】:

  • 谢谢 AntoniosK!在这种特殊情况下使用 ungroup 的原因是什么?
  • 我不希望分组(ID)保留在我的输出数据集上,因为我可能需要执行进一步的计算并且分组可能会影响这些。每当您在流程的特定阶段达到理想输出时,取消分组是一种很好的做法。
  • 还有问题吗?如果一个或多个标志特征的值为 TRUE,您将如何选择所有 ID?
  • 您想将这些 ID 作为向量获取吗?您想要数据集中的另一列吗?
  • 我为列找到了它:df %>% group_by(ID) %>% filter(any(flag == "TRUE")) %>% ungroup() 谢谢。您的解决方案将 ID 提取为向量是一件很棒的事情。
猜你喜欢
  • 2018-11-25
  • 1970-01-01
  • 2019-03-17
  • 1970-01-01
  • 2015-12-03
  • 1970-01-01
  • 1970-01-01
  • 2020-05-07
  • 2015-08-28
相关资源
最近更新 更多