Reputation: 21
I have the following data. I want to do a conditional filter where if C (confirmed) value for AMZN is present, then delete the row with E, and if no C, then keep E. In this case, we would have one C row for AMZN and one E row for AAPL.
Any ideas on how best to achieve this in R?
| AMZN| C| 1|
| AMZN| E| 2|
| AAPL| E| 2|
Upvotes: 2
Views: 66
Reputation: 78917
We could use dplyr
s filter and apply the conditions one by one, so:
The logic:
if V1
is AMZN
and V2
is C
then only rows with both conditions will be filtered,
additionaly using the |
operator we make a possibility to be filtered by setting
V2
to E
and V1
not to AMZN
library(dplyr)
filter(df, V1 == "AMZN" & V2 == "C" | V2 == "E" & V1 != "AMZN")
V1 V2 V3
1 AMZN C 1
2 AAPL E 2
Upvotes: 1
Reputation: 16836
Here is a possible base R solution:
df[as.logical(with(df, ave(V2, V1, FUN = function(i)
if(any(i == "C")) i != "E" else i == "E"))), ]
Output
V1 V2 V3
1 AMZN C 1
3 AAPL E 2
Or using data.table
:
library(data.table)
setDT(dt)[, .SD[if(any(V2 == "C")) V2 != "E" else V2 == "E"], .(V1)]
Data
df <-
structure(list(
V1 = c("AMZN", "AMZN", "AAPL"),
V2 = c("C", "E", "E"),
V3 = c(1L, 2L, 2L)
),
class = "data.frame",
row.names = c(NA,-3L))
Upvotes: 1
Reputation: 388817
You may try this with dplyr
-
library(dplyr)
df %>%
group_by(V1) %>%
filter(if(any(V2 == "C")) V2 != "E" else V2 == "E") %>%
ungroup
# V1 V2 V3
# <chr> <chr> <int>
#1 AMZN C 1
#2 AAPL E 2
data
It is easier to help if you provide data in a reproducible format
df <- structure(list(V1 = c("AMZN", "AMZN", "AAPL"), V2 = c("C", "E",
"E"), V3 = c(1L, 2L, 2L)), class = "data.frame", row.names = c(NA, -3L))
Upvotes: 2