Reputation: 1
i am new to R and hence going to ask a not-so-difficult question. I have a df which is about 200 columns and 1000 rows. It looks a bit like this
I need to calculate for each if the number of 2s is more than 0s in each row or vice-versa. If 2 is more than convert 0s in the same row to -1 or if 0 is more than convert 2 to -1.
I tried:
ifelse((rowSums(b=="0") > rowSums(b=="2")) , apply(b, 1 , function(b) b[b== "2" , ] <- "-1"), apply(b, 1 , function(b) b[b== "0" , ] <- "-1"))
but it gives the error:
Error in b[b == "2", ] <- "-1" : incorrect number of subscripts on matrix
Any help and suggestion are most welcome!
Upvotes: 0
Views: 83
Reputation: 1345
apply(data, 1, function(x) {
if (sum(x == 2, na.rm = TRUE) > sum(x == 0, na.rm = TRUE)) {
x[x == 0] <- -1
} else if {sum(x == 0, na.rm = TRUE) > sum(x == 0, na.rm = TRUE)) {
x[x == 2] <- -1
}
x
})
Upvotes: 0
Reputation: 887891
We can use apply
t(apply(b, 1, FUN = function(x) {
if(sum(x==2) > sum(x==0)) replace(x, x==0, -1)
else if (sum(x==0) > sum(x==2)) replace( x, x==2, -1)
else x}))
# ind1 ind2 ind3 ind4 ind5 ind6 ind7 ind8 ind9 ind10 ind11 ind12 ind13 ind14 ind15 ind16 ind17 ind18 ind19 ind20
#M8 -1 2 2 2 -1 2 2 1 1 -1 1 1 1 1 1 1 1 1 1 2
#M9 2 2 2 2 2 2 2 -1 -1 2 1 1 1 1 1 1 1 1 -1 1
#M17 1 1 -1 1 1 1 1 1 1 1 2 2 2 2 2 -1 -1 -1 -1 2
#M19 0 -1 0 0 0 0 -1 0 0 0 1 -1 1 -1 -1 1 1 1 1 1
Or we can do this based on rowSums
i1 <- rowSums(b == 0) > rowSums(b == 2)
b[b==0 & !i1] <- -1
b[b==2 & i1] <- -1
b
# ind1 ind2 ind3 ind4 ind5 ind6 ind7 ind8 ind9 ind10 ind11 ind12 ind13 ind14 ind15 ind16 ind17 ind18 ind19 ind20
#M8 -1 2 2 2 -1 2 2 1 1 -1 1 1 1 1 1 1 1 1 1 2
#M9 2 2 2 2 2 2 2 -1 -1 2 1 1 1 1 1 1 1 1 -1 1
#M17 1 1 -1 1 1 1 1 1 1 1 2 2 2 2 2 -1 -1 -1 -1 2
#M19 0 -1 0 0 0 0 -1 0 0 0 1 -1 1 -1 -1 1 1 1 1 1
b <- structure(list(ind1 = c(0, 2, 1, 0), ind2 = c(2, 2, 1, 2),
ind3 = c(2,
2, -1, 0), ind4 = c(2, 2, 1, 0), ind5 = c(0, 2, 1, 0), ind6 = c(2,
2, 1, 0), ind7 = c(2, 2, 1, -1), ind8 = c(1, 0, 1, 0), ind9 = c(1,
0, 1, 0), ind10 = c(0, 2, 1, 0), ind11 = c(1, 1, 2, 1), ind12 = c(1,
1, 2, -1), ind13 = c(1, 1, 2, 1), ind14 = c(1, 1, 2, -1), ind15 = c(1,
1, 2, -1), ind16 = c(1, 1, 0, 1), ind17 = c(1, 1, -1, 1), ind18 = c(1,
1, -1, 1), ind19 = c(1, 0, 0, 1), ind20 = c(2, 1, 2, 1)),
.Names = c("ind1",
"ind2", "ind3", "ind4", "ind5", "ind6", "ind7", "ind8", "ind9",
"ind10", "ind11", "ind12", "ind13", "ind14", "ind15", "ind16",
"ind17", "ind18", "ind19", "ind20"), row.names = c("M8", "M9",
"M17", "M19"), class = "data.frame")
Upvotes: 2