-1

I'm having trouble outputting the results of some R code into a data frame, for eventual export into CSV. I'm pretty new to R so I'm not sure what exactly the mistake is.

I have this input data set, called "ip_test":

ip        ip_end    country_name region_name city_name
702388992 702388994 US           West        LA

I'm then running this code:

g = 1
ip = as.numeric(ip_test[g,1])
df <- for(g in 1:as.numeric(nrow(ip_test)))
{   for(ip in as.numeric(ip_test[g,1]):as.numeric(ip_test[g,2])) 
    {   print(cbind(ip_address=ip,
            country_name = paste(ip_test[g,3], collapse=" "),
            region_name = paste(ip_test[g,4], collapse=" "),
            city_name = paste(ip_test[g,5], collapse=" ")))
    }
}

This is outputting these results:

     ip_address  country_name region_name city_name 
[1,] "702388992" "US"   "West"  "LA"
     ip_address  country_name region_name city_name 
[1,] "702388993" "US"   "West"  "LA"
     ip_address  country_name region_name city_name 
[1,] "702388994" "US"   "West"  "LA"

The problem I'm having is that the data frame "df" is not getting populated with any data, it remains "NULL (empty)". I'm not sure exactly what the issue is since the outputted data is what I want. I looked into matrix vs data frame issues, rbind on the output, ldply, as.data.frame, R list to data frame. I'm getting the same issue of no output to the data frame on every bit of code. I tried the "melt" function in the reshape2 library per Multidimensional array into data frame, which created a data frame 1 column wide by 11 rows long with the numbers 0-10, and this error: "Error in names(object) <- nm : 'names' attribute 1 must be the same length as the vector [0]"

I'm thinking this is something basic with the output but I'm not able to figure out the issue. Any help would be very appreciated.

Sm Ldad
  • 19
  • 2

1 Answers1

1

The problem with your code is you aren't assigning the new rows to the data.frame-- you're just printing them. What you want is rbind:

> ip_list=NULL
> for(i in ip_test$ip:ip_test$ip_end){
+   new_row=data.frame("ip_address"=i, "country_name"="US", "region_name"="West", "city_name"="LA")
+   ip_list=rbind(ip_list, new_row)  
+ }
> ip_list
  ip_address country_name region_name city_name
1  702388992           US        West        LA
2  702388993           US        West        LA
3  702388994           US        West        LA

Note that for loops are generally a bad way to do things in R. You'd probably be better off initializing an empty data frame with the number of columns you need, then assigning ip_address=start:end.

Matt
  • 954
  • 1
  • 9
  • 24
  • It worked! Thanks @Matt, I modified the code using your example and things are working perfect. I had to initialize the ip_list dataframe like this though: ip_list <- data.frame(ip_address = integer(), country_name = character(), region_name = character(), city_name = character(), stringsAsFactors = FALSE) – Sm Ldad Jul 26 '17 at 20:41
  • I understand about this being outside the scope of R's intended functionality, the full list of IPs comprises ~3 million rows. I'm sure there's a better tool for doing this but, limited as my skills are, I'm still more familiar with R than other languages. Thanks again! – Sm Ldad Jul 26 '17 at 20:51