Reputation: 359
Today I failed in doing a simple task:
I want to replace the maximum value in each row of a data frame with a specific individual value that I have computed before. I did not know how I could tell
DF <- structure(list(age_n = c(2, 3, 3, 3, 3, 3), female_noe_n = c(0.674555812063115,
0.681331945419623, 0.632659475334461, 0.649517172953091, 0.64918662986253,
0.667531771388686), male_noe_n = c(0.734797290317925, 0.742565052946117,
0.715791062610646, 0.729425965096302, 0.710171830071103, 0.734962561863205
), female_v_n = c(0.745209397670608, 0.86387436718214, 0.915191181991792,
1.01146185711779, 1.04658206048994, 1.11211222819373), male_v_n = c(0.783635031948367,
0.860486300503885, 0.909571949452249, 0.995595788770845, 1.03071599214299,
1.12996155508404)), row.names = c(NA, 6L), class = "data.frame")
ID <- apply(DF, 1, function(x) which.max(x))
# Now I need to overwrite the rowwise maximum by ceiling
overwrite_value <-
sapply(1:nrow(DF), function(x)
DF[x,ID[[x]]] %>% ceiling())
I guess there are simple solutions and I am stuck in something too complex
Upvotes: 3
Views: 893
Reputation: 887891
With row/column indexing it will be more efficient i.e. get the column index per row for the max
value with max.col
, cbind
with the row sequence to return a matrix of row/column index, extract the value and assign (based on the OP's description - I want to replace the maximum value in each row of a data frame with a specific individual value that I have computed before
)
m1 <- cbind(seq_len(nrow(DF)), max.col(DF[-1]))
DF[-1][m1] <- 5
-output
> DF
age_n female_noe_n male_noe_n female_v_n male_v_n
1 2 0.6745558 0.7347973 0.7452094 5.0000000
2 3 0.6813319 0.7425651 5.0000000 0.8604863
3 3 0.6326595 0.7157911 5.0000000 0.9095719
4 3 0.6495172 0.7294260 5.0000000 0.9955958
5 3 0.6491866 0.7101718 5.0000000 1.0307160
6 3 0.6675318 0.7349626 1.1121122 5.0000000
NOTE: If it is a vector of values to replace i.e. one element for each row, just assign it to that vector
DF[-1][m1] <- c(5, 10, 5, 15, 20, 5)
Upvotes: 2
Reputation: 79246
Here is a dplyr solution:
library(dplyr)
individual_value <- 5
DF %>%
rowwise() %>%
mutate( x = max(c_across(2:5))) %>%
mutate(across(2:5, ~case_when(. == x ~ individual_value,
TRUE ~ .)), .keep="unused"
)
age_n female_noe_n male_noe_n female_v_n male_v_n
<dbl> <dbl> <dbl> <dbl> <dbl>
1 2 0.675 0.735 0.745 5
2 3 0.681 0.743 5 0.860
3 3 0.633 0.716 5 0.910
4 3 0.650 0.729 5 0.996
5 3 0.649 0.710 5 1.03
6 3 0.668 0.735 1.11 5
Upvotes: 2