James Rodriguez
James Rodriguez

Reputation: 119

R populate data frame in a loop not working

I could not find answers that worked in a google search. My dataframe is not populating I don't know why. This seems simple but it is not working. Can anyone help?

x<- 50:1
y<- -44:5

theDF <- data.frame(x,y)

# add new column
theDF["GName"] <- 'NA'

divToG <- function (a)
{
   counter = 1
   g_number = 1

   # loop to populate new column
   for (i in 1:nrow(theDF))
   {
      theDF$GName[i] = paste("GName", toString(g_number))  # NOT WORKING!
      g_number = g_number + 1
   }    
}

#call the function
divToG (theDF)

Why is it not populating theDF$GName[i]? If the loop is successful, the column should be GName 1, GName 2, Gname 3, etc instead of NA, but I cannot get it to change from NA.

Upvotes: 0

Views: 100

Answers (2)

alistaire
alistaire

Reputation: 43354

If you paste a single string to a sequence of numbers, the numbers will be coerced to characters and the string will be pasted onto each. Thus, the first step is to get your sequence the way you want with :, seq, or occasionally sequence. If you're trying to make a grouping variable, rep's each parameter is helpful:

rep(1:5, each = 3)
# [1] 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5

Now just paste on a prefix (here with paste0 for sep = ""):

paste0('GName', rep(1:5, each = 10))
#  [1] "GName1" "GName1" "GName1" "GName1" "GName1" "GName1" "GName1" "GName1" "GName1" "GName1"
# [11] "GName2" "GName2" "GName2" "GName2" "GName2" "GName2" "GName2" "GName2" "GName2" "GName2"
# [21] "GName3" "GName3" "GName3" "GName3" "GName3" "GName3" "GName3" "GName3" "GName3" "GName3"
# [31] "GName4" "GName4" "GName4" "GName4" "GName4" "GName4" "GName4" "GName4" "GName4" "GName4"
# [41] "GName5" "GName5" "GName5" "GName5" "GName5" "GName5" "GName5" "GName5" "GName5" "GName5"

Upvotes: 0

Adam Quek
Adam Quek

Reputation: 7163

you need to put in return command in the function:

divToG <- function (a)
{
  counter = 1
  g_number = 1

  # loop to populate new column
  for (i in 1:nrow(theDF))
  {
    theDF$GName[i] = paste("GName", toString(g_number))  # NOT WORKING!
    g_number = g_number + 1
  }    
  return(theDF)
}

head(divToG (theDF))
   x   y   GName
1 50 -44 GName 1
2 49 -43 GName 2
3 48 -42 GName 3
4 47 -41 GName 4
5 46 -40 GName 5
6 45 -39 GName 6

A more elegant way would be to do away with the function and just run:

theDF$GName <- paste("GName", 1:nrow(theDF))

Upvotes: 2

Related Questions