【问题标题】:Conditional replacement of values in dataframe with NA用 NA 有条件地替换数据框中的值
【发布时间】:2020-03-14 09:04:56
【问题描述】:

对 R 并不陌生,但我是更高级的 R 技术的新手,我遇到了一个问题。我正在使用一个有点大的数据集(不是很大,但总共有大约 65000 行数据,包含 18 个试验)。链接在这里:https://www.dropbox.com/s/qn6fldj9z6w21b2/wtvstyr%20%282%29.csv?dl=0,我一直在使用它作为数据框。这是手头的任务:

我需要根据来自方向和 Y 列的信息逐个试验有条件地替换速度值。这是我的条件:如果方向为 TRUE 并且 Y 的前 5 个值 180,我需要将 Trial x 的所有速度值替换为 NA。如果方向为 FALSE 并且 Y 的前 5 个值不 > 180,那么我只需要根据具体情况进行处理。

我有以下使用 dplyr 的代码,来自我在这里找到的一些解决方案(主要来自 dplyr replacing na values in a column based on multiple conditions):

wtvstyr <- wtvstyr %>% 
  mutate(velocity = case_when(direction == TRUE & Y<20 ~ NA_real_, TRUE ~ velocity))
wtvstyr <- wtvstyr %>%
  mutate(velocity = case_when(direction == FALSE & Y>180 ~ NA_real_, TRUE ~ velocity))

这可以根据具体情况解决我的问题。至于放弃整个试验,我很困惑。我试图用 ifelse 包裹在一个 dplyr 管道中,第一个值的索引,但我必须承认我不知道我在做什么。以下是 TRUE/Using If/Else on a data frame:

wtvstyr %>%
  group_by(Trial) %>%
  ifelse(case_when(direction == TRUE & Y[1]<20), velocity, NA_real_)

但是,当我尝试这样做时,我收到了一个未使用的 NA 参数错误。

任何帮助将不胜感激!如果有更好的方法来完全做到这一点(重新,屏蔽值或我不知道的其他方式),任何指导都会很棒。谢谢!

编辑

这是我的数据集的一个可重现的迷你示例:

require(tidyverse)

set.seed(80)

Trial <- c(rep(1, 40), rep(2, 40))
Y <- c(sample(0:200, 80, replace=TRUE))
Time <- c(1:80)
Direction1 <- c(rep("TRUE", 10), rep("FALSE", 10))
Direction <- c(rep(Direction1, 4))
example <- data.frame(Trial, Time, Y, Direction)

example$Y2 = example$Y 

shift <- function(x, n){
  c(x[-(seq(n))], rep(NA, n))
}

example$Y2 <- shift(example$Y2, 1)
example$velocity <- as.numeric(example$Y2) - as.numeric(example$Y)
example <- example[-c(5)]

#bit of code to remove velocities when they meet conditions I don't want:
example <- example %>% 
  mutate(velocity = case_when(Direction == TRUE & Y<20 ~ NA_real_, TRUE ~ velocity))
example <- example %>%
  mutate(velocity = case_when(Direction == FALSE & Y>180 ~ NA_real_, TRUE ~ velocity))

使用第二段代码,我可以逐个删除我的值(我希望这个例子能阐明我的意思)。我仍然无法根据 Y 中的前五个值来编码某种方式来识别哪些试验需要完全丢弃。

因此,例如,在 Trial==1 和 Direction==TRUE 的数据的第一小节中,如果该小节中的前五个数据点中的任何一个

在我拥有的 set.seed 中,Trial==1 和 Direction==TRUE 下的前五个 Y 值是 138、40、32、192 和 99。在这里,因为没有值 180,我需要删除所有对应于 Trial==1 和 Direction==FALSE 的值。但是,稍后,还有另一种情况,即 Trial=1 和 Direction==FALSE。我想单独保留该案例并根据前五个值对其进行评估。如果我需要附加另一列编号,我可以将它们分开的方向重复,我可以这样做。

如果您需要更多说明,请告诉我,再次感谢您提供的任何帮助。

【问题讨论】:

  • 如果您尝试保留/丢弃行,请尝试 dplyr::slice 或 dplyr::filter。
  • 您能否创建一个可重现的小示例并在此处使用dput 共享数据并显示基于此的预期输出?请阅读此处了解如何提供reproducible example
  • 如果说“如果方向为 TRUE 并且 Y 的前 5 个值不
  • 还有一件事。我现在正在调查你的数据。对于试验 1,我看到 TRUE 和 FALSE。当您说“direction == TRUE”时,这是否意味着方向上的所有数据点都具有 TRUE 或 FALSE?否则,您的确切条件是什么。我想你想更多地描述你的情况。

标签: r dataframe dplyr conditional-statements


【解决方案1】:

使用 GenesRus 交给我的代码,我能够修改代码以选择我想要的试验:

trialdata_filter <- trialdata %>%
  mutate(direction= as.logical(direction)) %>% 
  mutate(is.special = case_when(direction == FALSE & Y > 180 ~ TRUE, direction == TRUE & Y <20 ~ TRUE, TRUE ~ FALSE)) %>% 
  group_by(bartrial) %>%
  filter(!any(is.special[1:25] == TRUE))

感谢您的帮助!

【讨论】:

    【解决方案2】:

    如果我大致收集了您要查找的内容,那么最简单的方法是创建一个特殊列来保存您想要保留在其他条件之外的内容,然后手动将它们设置在 case_when 中。之后,您可以group_by Trial and Direction 并设置过滤器以仅选择那些符合条件的 Trial/Direction 组(其中该组中前五个中的任何值不小于 20 或小于 180,具体取决于方向,否则是特殊情况)。从那里,您可以切片以获得前 5 个,但如果您也想要特殊行,我已经过滤了。

    example %>%
      mutate(Direction= as.logical(Direction)) %>% 
      mutate(is.special = case_when(
        Trial== 1 & Direction == FALSE & Y == 30 ~ TRUE,
        TRUE ~ FALSE ## This is a weird convention, but TRUE just catches if nothing else evaluates TRUE and in this case, we want that to be 
      )) %>% 
      group_by(Trial, Direction) %>% 
      filter(
        is.special |
        (Direction == TRUE & !any(Y[1:5] < 20)) |
        (Direction == FALSE & !any(Y[1:5] > 180))
        ) %>% 
      filter(
        is.special | row_number() <= 5
      )
    

    any 是一个很好的函数,它会查看组的成员以查看是否有任何满足条件。由于我否定它,您可能想使用all,但我想使用您上面的标志来保持一致。

    【讨论】:

    • 感谢您的帮助,GenesRus!我一直在使用您发布的代码,但我有一些问题:您为什么在第一个 case_when 中指定 Y==30?其次,如果我将标签变量分配给 Direction(即 True1、False1、True2、False2 等),是否更容易按 Direction 分组?
    • 哦,只是为了挑选一个特定的,否则会被过滤掉。听起来您需要这样的特殊情况。
    • 方向很好,我想。最好不要用其他地方的数据填满你的小标题,imo。将其视为一个因素有点奇怪,但这很容易解决,并且在您的原始数据中可能不是必需的。您可以根据需要对任意数量的变量进行分组,所以我会保留它,除非您使用新的方向以某种方式添加到信息内容中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 2020-03-24
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 2019-09-08
    相关资源
    最近更新 更多