Kristen Delevich PhD
Kristen Delevich PhD

Reputation: 19

How to filter row by lowest value in a column using a for loop in R

This is not elegant, but for each file I want to filter the row when dvdt first meets/exceeds 15. I first filtered for each file dvdt values >= 15. Then I tried to filter rows with the minimum time value in this new data frame. The problem is that min(time) returns the global minimum across all files, whereas I'd like to identify the lowest time value within each file. Any help would be appreciated!

df <- structure(list(file = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L), .Label = c("19509002.abf", "19509007.abf"
), class = "factor"), time = c(4.800000191, 4.849999905, 4.900000095, 
4.949999809, 5, 5.050000191, 5.099999905, 5.150000095, 5.199999809, 
5.25, 5.300000191, 5.349999905, 5.400000095, 5.449999809, 5.5, 
4.849999905, 4.900000095, 4.949999809, 5, 5.050000191, 5.099999905, 
5.150000095, 5.199999809, 5.25, 5.300000191, 5.349999905, 5.400000095, 
5.449999809), V = c(-34.8815918, -29.96826172, -23.65112305, 
-16.44897461, -7.843017578, 3.234863281, 15.86914063, 27.6184082, 
37.109375, 44.18945313, 49.37744141, 52.94799805, 55.41992188, 
57.00683594, 57.80029297, -36.28540039, -31.92138672, -24.78027344, 
-16.3269043, -6.683349609, 5.310058594, 18.89038086, 31.21948242, 
40.67993164, 47.24121094, 51.63574219, 54.32128906, 55.9387207
), dvdt = c(47.6074219, 98.2666016, 126.342773, 144.042969, 172.119141, 
221.557617, 252.685547, 234.985352, 189.819336, 141.601563, 103.759766, 
71.4111328, 49.4384766, 31.7382813, 15.8691406, 27.4658203, 87.2802734, 
142.822266, 169.067383, 192.871094, 239.868164, 271.606445, 246.582031, 
189.208984, 131.225586, 87.890625, 53.7109375, 32.3486328)), row.names = c(NA, 
28L), class = "data.frame")

vthresh <- data.frame()
for (i in unique(df$file)){
  vthresh = rbind(vthresh, df %>% filter(file == i, time == min(time)))
}

Upvotes: 0

Views: 81

Answers (2)

Kristen Delevich PhD
Kristen Delevich PhD

Reputation: 19

I built on Marc's answer and the code below works!

df_sub <- subset(df, dvdt >= 15)
df_agg <- aggregate(df_sub$time, by = list(df_sub$file), min) 
colnames(df_agg) <- c('file', 'time')
vthresh <- merge(df_sub, df_agg, by=c("file","time"))

Upvotes: 1

Marc
Marc

Reputation: 2410

# filter dvdt values >= 15
dfsub <- subset(df, dvdt >= 15)

# identify the lowest time value within each file
aggregate(dfsub$time, by = list(dfsub$file), min)

which gives the following output:

       Group.1    x
1 19509002.abf 4.80
2 19509007.abf 4.85

Upvotes: 1

Related Questions