Reputation: 123
I want to replace each value of a row of data.frame, for with a equal sized logical matrix has the value TRUE, by the value of a corresponding row of a vector. Here is an example:
> df1
[,1] [,2] [,3] [,4]
[1,] 2 8 9 4
[2,] 2 6 6 6
[3,] 4 9 4 8
> a
[,1] [,2] [,3] [,4]
[1,] TRUE FALSE FALSE TRUE
[2,] TRUE FALSE FALSE FALSE
[3,] TRUE FALSE TRUE FALSE
> df2
[1] 5 4 6
So the result should look like this:
> df1
[,1] [,2] [,3] [,4]
[1,] 5 8 9 5
[2,] 4 6 6 6
[3,] 6 9 6 8
Is there any way to do this without the use of loops? Thanks
Upvotes: 1
Views: 1673
Reputation: 887951
We replicate 'df2' by the row
of 'a' or 'df1', based on the logical matrix of 'a', we change the value
ifelse(a, df2[row(a)], df1)
# [,1] [,2] [,3] [,4]
#[1,] 5 8 9 5
#[2,] 4 6 6 6
#[3,] 6 9 6 8
If it is data.frame
, then we need to just change as.matrix(df1
) and it should work in both cases
df1[] <- ifelse(a, df2[row(a)], as.matrix(df1))
Or another option is
(df1*!a) + (df2[row(a)]*a)
# [,1] [,2] [,3] [,4]
#[1,] 5 8 9 5
#[2,] 4 6 6 6
#[3,] 6 9 6 8
NOTE: Both the output are matrix
as showed in the expected output and the initial dataset in the OP's example is matrix
. But it works with both data.frame
and matrix
(with the edit)
Upvotes: 1
Reputation: 4187
You need some advanced subsetting for this:
df1[a] <- df2[row(a)[a]]
the output:
> df1
V1 V2 V3 V4
1 5 8 9 5
2 4 6 6 6
3 6 9 6 8
This solution works on both a dataframe or a matrix.
Upvotes: 2