【问题标题】:How do I delete rows within a subset of a dataframe如何删除数据框子集中的行
【发布时间】:2018-12-25 04:46:45
【问题描述】:

我正在过滤数据以进行分析,但偶然发现了一个我找不到解决方案的问题。我确实查看了 prepdat-package 但它似乎不能满足我的需求。 我的数据框(df)由几个参与者的反应时间组成,测量时间超过 4 个块。为了过滤掉异常值,我需要对每个参与者的每个块应用(平均 +/- 2.5 sd)规则。

我尝试创建自己的函数,以便将此规则应用于我的数据帧的每个子部分(分别针对每个参与者的每个块)。我创建了下面的函数,因此我可以将它与 for 循环一起使用(这个循环在 R 中可能不是最佳的,但这不是这里的主要问题):

filter <- function(subject, block){ 
m   <- mean(df[df$subj == subject & df$block == block,3])
stdv<- sd(df[df$subj == subject & df$block == block,3])
lowerbound <- m - 2.5 * stdv
upperbound <- m + 2.5 * stdv
outliers <- which((df[(df$subj == subject & df$block == block),3] <= lowerbound |df[(df$subj == subject & df$block == block),3] >= upperbound)) #Here I retrieve the index for all the rows I need to eliminate
df <<- df[-c(outliers), ] 
}

我无法理解这个索引。对于第一个主题的第一个块似乎没有问题,该函数删除了正确的行。但是对于下一个块(和主题),“异常值”还包含子集(主题和块)的正确索引,我要求在函数中“选择”,但是当我尝试通过它消除行时,它看起来像索引应用于我的整个数据框的索引,而不是应用于我在函数中使用的主题和块的特定子集。有什么我遗漏的东西,或者(还)不知道要使用的东西吗?还是我的整体思维方式不对??(我还在适应R)

subj block  rt
1     1     2 345
2     1     2 118
3     1     2 302
4     1     2 698
5     1     2 154
6     2     3 347
7     2     3 391
8     2     3 414
9     2     3 427
10    2     3 369
11    6     1 685
12    6     1 369
13    6     1 457
14    6     1 566
15    6     1 542

【问题讨论】:

  • 您能否提供(部分)您的数据,以便创建其他人可以运行的reproducible example
  • 你的 upperbound &lt;- m - 2.5 * stdv 但应该是 upperbound &lt;- m + 2.5 * stdv
  • 是的,我改变了我的错误。感谢您指出。

标签: r dataframe indexing subset


【解决方案1】:

dplyr 在这里使用可能会更好:

df %>% 
group_by(subj, block) %>% 
dplyr::summarise(lb = mean(rt) - 2.5 * sd(rt), 
                 ub = mean(rt) + 2.5 * sd(rt)) %>%
inner_join(df, by = c("subj", "block")) %>%
ungroup() %>% 
filter(rt > lb & rt < ub)

现在这会产生相同大小的 tibble,因为根据您的定义没有异常值。如果我将您的定义更改为 1.5 而不是 2.5,那么我们会得到 20 行。这是您对异常值的定义的问题。

【讨论】:

    猜你喜欢
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    • 2020-03-30
    • 2023-01-05
    相关资源
    最近更新 更多