通过分组观察R中的变量进行子集

时间:2017-06-09 00:52:46

标签: r

因此,如果您这样做,您将获得与我正在使用的数据框类似的数据框

test <- Indometh[Indometh$time %in% c(1.00,3.00,6.00),]
dil <- c(50,500,5000)
test$dilution <- dil
test <- test[-c(3,7,11,17),]
test[14,4] <- 50
test$time <- gsub(1, "run_1", test$time)
test$time <- gsub(3, "run_3", test$time)
test$time <- gsub(6, "run_6", test$time)


   Subject  time conc dilution
        1 run_1 0.48       50
        1 run_3 0.12      500
        2 run_1 0.70       50
        2 run_3 0.32      500
        2 run_6 0.12     5000
        3 run_3 0.22      500
        3 run_6 0.08     5000
        4 run_1 0.89       50
        4 run_6 0.07     5000
        5 run_1 0.39       50
        5 run_3 0.13      500
        5 run_6 0.10     5000
        6 run_1 0.84       50
        6 run_6 0.10       50

我需要做的是应用以下逻辑。

对于每个受试者,如果稀释度为50且有任何其他稀释度,请保留其他稀释液。

如果稀释度为50且只有其他稀释度50可用,则保留该对象的所有稀释度50。

所以我的结果数据框应如下所示:

testres <- test[-c(1,3,8,10),]

 Subject  time conc dilution
       1 run_3 0.12      500
       2 run_3 0.32      500
       2 run_6 0.12     5000
       3 run_3 0.22      500
       3 run_6 0.08     5000
       4 run_6 0.07     5000
       5 run_3 0.13      500
       5 run_6 0.10     5000
       6 run_1 0.84       50
       6 run_6 0.10       50

由于

PS:这个问题难以措辞,对于如何更好地标题这个问题有什么建议吗?

3 个答案:

答案 0 :(得分:3)

同样使用dplyr但是更短一些:

library(dplyr)
test %>% 
    group_by(Subject) %>% 
    mutate(all50 = all(dilution == 50)) %>% 
    filter((all50 & dilution == 50) | (! all50 & dilution != 50))

输出:

# A tibble: 10 x 5
   Subject   time  conc dilution all50
     <int> <fctr> <dbl>    <int> <lgl>
 1       1  run_3  0.12      500 FALSE
 2       2  run_3  0.32      500 FALSE
 3       2  run_6  0.12     5000 FALSE
 4       3  run_3  0.22      500 FALSE
 5       3  run_6  0.08     5000 FALSE
 6       4  run_6  0.07     5000 FALSE
 7       5  run_3  0.13      500 FALSE
 8       5  run_6  0.10     5000 FALSE
 9       6  run_1  0.84       50  TRUE
10       6  run_6  0.10       50  TRUE

答案 1 :(得分:1)

以下是使用dplyr的解决方案。

library(dplyr)

# Group the data frame by Subject
test2 <- test %>% group_by(Subject) 

# Filter Subjects with all dilution == 50
test3 <- test2 %>% filter(all(dilution == 50))

# Filter out other records with dilution == 50
test4 <- test2 %>%
  filter(!all(dilution == 50)) %>%
  filter(dilution != 50)

# Combine the data frames
test_final <- test3 %>%
  bind_rows(test4) %>%
  ungroup() %>%
  mutate(Subject = as.numeric(as.character(Subject))) %>%
  arrange(Subject)

答案 2 :(得分:1)

以下是使用data.table

的选项
library(data.table)
setDT(test)[, .SD[(all(dilution == 50) & dilution == 50)|
         (!all(dilution == 50) & dilution !=50)], Subject]
#    Subject  time conc dilution
# 1:       1 run_3 0.12      500
# 2:       2 run_3 0.32      500
# 3:       2 run_6 0.12     5000
# 4:       3 run_3 0.22      500
# 5:       3 run_6 0.08     5000
# 6:       4 run_6 0.07     5000
# 7:       5 run_3 0.13      500
# 8:       5 run_6 0.10     5000
# 9:       6 run_1 0.84       50
#10:       6 run_6 0.10       50