Reputation: 485
I would like to create a table depending on if elements in another table have certain values or characters in R.
Let´s say that I have this table:
test <- data.frame(col1=c(1,2,3,4,5), col2=c("AA","CC","GG","TT", "GG"))
I would like to create a table filing a row with certain values if the character in col2 is AA, other values if is CC, and so on.
I am trying the next script
test2<-c()
for(i in 1:nrow(test)) {
if(test$col2[i]=="AA"){
test2 <- rbind(test2, data.frame(0.91, 0.03, 0.03, 0.03))
} else if (test$col2[i]=="CC"){
test2 <- rbind(test2, data.frame(0.03, 0.91, 0.03, 0.03))
} else if (geno_no_miss$V5[i] == "GG"){
test2 <- rbind(test2, data.frame(0.03, 0.03, 0.91, 0.03))
} else {
test2 <- rbind(test2, data.frame(0.03, 0.03, 0.03, 0.91))
}
}
This is producing the next optput:
X0.91 X0.03 X0.03.1 X0.03.2
1 0.91 0.03 0.03 0.03
2 0.91 0.03 0.03 0.03
3 0.91 0.03 0.03 0.03
4 0.91 0.03 0.03 0.03
5 0.91 0.03 0.03 0.03
My desired output in this example is:
V1 V2 V3 V4
1 0.91 0.03 0.03 0.03
2 0.03 0.91 0.03 0.03
3 0.03 0.03 0.91 0.03
4 0.03 0.03 0.03 0.91
5 0.03 0.03 0.91 0.03
Having the 0.91 in a different position depending on if in my table I have AA or CC or GG or TT. Could you please tell me how I could achieve this?
Upvotes: 0
Views: 844
Reputation: 79228
First create a dataframe that has the results you need
results <- data.frame(key = c('AA', 'CC', 'GG', 'other'),
V1 = c(0.91,0.03, 0.03,0.03),
V2 = c(0.03, 0.91,0.03,0.03),
V3 = c(0.03,0.03, 0.91, 0.03),
V4 = c(0.03,0.03, 0.03, 0.91))
Then do a join/merge:
library(tidyverse)
test %>%
mutate(key = ifelse(col2%in%res$key, col2, 'other'))%>%
left_join(res, 'key')%>%
select(-key)
col1 col2 V1 V2 V3 V4
1 1 AA 0.91 0.03 0.03 0.03
2 2 CC 0.03 0.91 0.03 0.03
3 3 GG 0.03 0.03 0.91 0.03
4 4 TT 0.03 0.03 0.03 0.91
5 5 GG 0.03 0.03 0.91 0.03
Upvotes: 0
Reputation: 388982
I would do it a bit differently. Growing objects/dataframe in a for
loop is inefficient, use lists instead. Replace for
loop with lapply
since lapply
naturally returns output as a list.
Write a function which returns a dataframe based on your condition.
return_data <- function(x) {
if(x == 'AA') {
data.frame(V1 = 0.91, V2 = 0.03,V3 = 0.03, V4 = 0.03)
} else if(x == 'CC') {
data.frame(V1 = 0.03, V2 = 0.91,V3 = 0.03, V4 = 0.03)
} else if(x == 'GG') {
data.frame(V1 = 0.03, V2 = 0.03,V3 = 0.91, V4 = 0.03)
} else {
data.frame(V1 = 0.03, V2 = 0.03,V3 = 0.03, V4 = 0.91)
}
}
do.call(rbind, lapply(test$col2, return_data))
# V1 V2 V3 V4
#1 0.91 0.03 0.03 0.03
#2 0.03 0.91 0.03 0.03
#3 0.03 0.03 0.91 0.03
#4 0.03 0.03 0.03 0.91
#5 0.03 0.03 0.91 0.03
You can also use purrr::map_df(test$col2, return_data)
which will return the same output.
Upvotes: 3