6

I have a data table made of 3 columns that is assigned to a variable g.

g
#      V1   V2 V3
# [1,]  1  Yes  3
# [2,]  4   No  6
# [3,]  7   No  9
# ...

I'm trying to create a list, m, by checking to see if the values in g[,2] are "Yes" or "No", and then pasting some string into m.

m <- for(i in 1:nrow(g)){
  if(g[i,2]=='No'){
    paste0("ABC", g[i,1], "DEF", g[i,2], "GHI", g[i,3],"\n")
  } else if(g[i,2]=='Yes'){
    paste0("GHI", g[i,1], "DEF", g[i,2], "ABC", g[i,3],"\n")
  } else {NULL}
}

m
# NULL

However when I try to return m, it just returns NULL. I want m to look like this:

m
# ABC1DEFYesGHI3
# GHI2DEFNoABC9

Can someone point out what I am doing wrong here? Thank you very much!

alki
  • 3,334
  • 5
  • 22
  • 45

2 Answers2

12

A for loop doesn't return anything in R. Typically you would want to update another variable that you would continue using after the for loop. For example:

m <- "intialize" # initialize, sometimes better as just `list()`
for(i in 1:nrow(g)){
  if(g[i,2]=='No'){
    # paste into position i of vector m
    m[i] <- paste0("ABC", g[i,1], "DEF", g[i,2], "GHI", g[i,3],"\n") 
  } else if(g[i,2]=='Yes'){
    # paste into position i of vector m
    m[i] <- paste0("ABC", g[i,1], "DEF", g[i,2], "GHI", g[i,3],"\n")
  } else {
  NULL
  }
}
m
> ... 
Brandon Bertelsen
  • 43,807
  • 34
  • 160
  • 255
0

You can use print() function and capture.output() as following

#generate data, I used 3 lists, which in your case are 3 columns
col1<-c("Yes","No","Maybe","Yes","No")
col2<-1:5
col3<-5:1
data<-cbind(col1,col2,col3)
#check the data table
#     col1    col2 col3
#[1,] "Yes"   "1"  "5" 
#[2,] "No"    "2"  "4" 
#[3,] "Maybe" "3"  "3" 
#[4,] "Yes"   "4"  "2" 
#[5,] "No"    "5"  "1" 
#here is the function for your transformation
m<-function(col1,col2,col3){
  for (i in 1:5){
  if (col1[i]=="Yes") {res=paste("ABC",col2[i],"DEF",col3[i],sep="")
  print(paste(i, res))}
  else if(col1[i]=="No") {res=paste("DEF",col2[i],"ABC",col3[i],sep="")
  print(paste(i, res))}
  }
}
#capture the results 
res<-capture.output(m(data[,"col1"],data[,"col2"],data[,"col3"]))
#show results 
as.data.frame(res)
#               res
#1 [1] "1 ABC1DEF5"
#2 [1] "2 DEF2ABC4"
#3 [1] "4 ABC4DEF2"
#4 [1] "5 DEF5ABC1"
Leo
  • 199
  • 2
  • 4