0

I have this structure:

census <- structure(list(date1 = c(1993L, 1993L, 1993L), dbh1 = c(NA, 40.7, 
67), liana1 = c(NA, 2, 3), date2 = c(1994L, 1994L, 1994L), dbh2 =
c(NA, 
41.3, NA), date3 = c(1995L, 1995L, 1995L), dbh3 = c(NA_real_,  NA_real_, NA_real_), date4 = c(1996L, 1996L, 1996L), dbh4 =
c(NA_real_,  NA_real_, NA_real_), date5 = c(1998L, 1998L, 1998L), dbh5
= c(NA_real_,  NA_real_, NA_real_), date6 = c(2000L, 2000L, 2000L), dbh6 = c(NA_real_,  NA_real_, NA_real_), date7 = c(2003L, 2003L,
2003L), dbh7 = c(NA_real_,  NA_real_, NA_real_), liana7 = c(NA_real_,
NA_real_, NA_real_), 
    date8 = c(2006L, 2006L, 2006L), dbh8 = c(20.1, NA, NA), date9 = c(2009L, 
     2009L, 2009L), dbh9 = c(24.2, NA, NA), liana9 = structure(c(4L, 
     1L, 1L), .Label = c("", ",", "+", "1", "2", "3"), class = "factor"), 
     death = c(NA, 1995L, 1994L), wd = c(0.6185, 0.6185, 0.6185
     )), .Names = c("date1", "dbh1", "liana1", "date2", "dbh2",  "date3", "dbh3", "date4", "dbh4", "date5", "dbh5", "date6", "dbh6", 
 "date7", "dbh7", "liana7", "date8", "dbh8", "date9", "dbh9", 
 "liana9", "death", "wd"), row.names = c(NA, 3L), class = "data.frame")

And I want to get each "dbh" (1 to 9) column and apply an equation those values. Then I was trying to add those results into new columns in my dataframe (adding new 9 columns). For that I came up with this loop:

 dbh =c("dbh1","dbh2","dbh3","dbh4","dbh5","dbh6","dbh7","dbh8","dbh9")



for (i in 1:9) {
     census[,31+i] <- census$wd * exp(-1.499 + 2.148 * log(census$dbh[i]) +
     0.207*(log(census$dbh[i]))^2 - 0.0281*(log(census$dbh[i]))^3) / 1000                                 
 }

I am starting to learn how to loop, so I am not even sure if that would work, but the error that I get is:

Error in log(census$dbh[i]) :    non-numeric argument to mathematical
function

Any ideas how to fix this? Thanks in advance!

Simon O'Hanlon
  • 58,647
  • 14
  • 142
  • 184
TWest
  • 765
  • 2
  • 6
  • 27
  • Try running the inner part of your loop using the current `i`. I suspect the problem is with your code not your loop. – Ari B. Friedman Aug 16 '13 at 19:39
  • `census$dbh[i]` is the main problem. You are expecting this expression to be evaluated. It will not be. See [**another answer I gave**](http://stackoverflow.com/a/18228613/1478381) for more details about this. Instead use `[` in place of `$` like this: `census[ , paste0( "dbh" , i ) ]` or `census[ , dbh[i] ]` – Simon O'Hanlon Aug 16 '13 at 21:26

2 Answers2

0

2 things:

1) You need to replace census$dbh[i] with census[dbh[i]] in your calculation. I don't fully understand why this matters, but it does.

2) After that, you should check where the results are going. In your example they go to columns 32-40, but there are only 23 columns in the data.frame so R gives an error because it does not like the blank columns this will create. For the example you need census[,23+i] for the results of the for loop to work.

John Paul
  • 12,196
  • 6
  • 55
  • 75
0

Use this instead:

l <- log(census[,grepl("^dbh",names(census))])
Result <- census$wd * exp(-1.499 + 2.148*l + 0.207*l^2 - 0.0281*l^3) / 1000

Result:

      dbh1    dbh2 dbh3 dbh4 dbh5 dbh6 dbh7      dbh8      dbh9
1       NA      NA   NA   NA   NA   NA   NA 0.2626273 0.4272698
2 1.626766 1.68795   NA   NA   NA   NA   NA        NA        NA
3 5.558074      NA   NA   NA   NA   NA   NA        NA        NA

If you want to add this to the original dataframe, use this:

names(Result) <- paste("transformed", names(Result))
cbind(census, Result)
Ferdinand.kraft
  • 12,579
  • 10
  • 47
  • 69