I have a dataframe as such:
| x | y |
|---|---|
| a | e |
| b | f |
| c | g |
| d | h |
and I have a dataframe of bool values as such:
| x | y |
|-------|-------|
| FALSE | TRUE |
| FALSE | TRUE |
| TRUE | FALSE |
| TRUE | FALSE |
(actually this stuff came out as a result from a different post, but that's not really relevant cos this is a stand-alone question)
I'm just searching for a way to apply the df with the bool values to the 'regular' df, and get this:
| x | y |
|---|---|
| | e |
| | f |
| c | |
| d | |
This question asked a very similar question, but the solutions diverged into different directions.
I have tried a wide variety of different indexing schemes, but they all fail to retain the rectangular structure of the output that I desire.
df[mask]
was too good to be true as well.
Any advice much appreciated.
My data:
df <- data.frame(
x = c('a', 'b', 'c', 'd'),
y = c('e', 'f', 'g', 'h'), stringsAsFactors = F
)
mask <- structure(list(x = c(FALSE, FALSE, TRUE, TRUE), y = c(TRUE, TRUE,
FALSE, FALSE)), .Names = c("x", "y"), row.names = c(NA, -4L), class = "data.frame")
The simplest approach is (thanks to @thelatemail for inspiration)
df[!mask] <- ""
# x y
# 1 e
# 2 f
# 3 c
# 4 d
Which works because !
coerces mask
to a logical matrix (so there's no need for the as.matrix()
call)
str(mask)
# 'data.frame': 4 obs. of 2 variables:
# $ x: logi FALSE FALSE TRUE TRUE
# $ y: logi TRUE TRUE FALSE FALSE
str(!mask)
# logi [1:4, 1:2] TRUE TRUE FALSE FALSE FALSE FALSE ...
# - attr(*, "dimnames")=List of 2
# ..$ : NULL
# ..$ : chr [1:2] "x" "y"
## and
class(!mask)
# "matrix"
A couple of ifelse
s will also work
df$x <- ifelse(mask$x, df$x, "")
df$y <- ifelse(mask$y, df$y, "")
We can use replace
replace(df, !mask, "")
# x y
#1 e
#2 f
#3 c
#4 d
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With