"could not find function" for a data.frame element

I'm an R novice (first time posting) trying to create a new column for an existing data.frame based on the last character in an existing column. The data.frame elements look OK but I always receive an error message like:

Error in Plot.ID(endsWith, "D") : could not find function "Plot.ID"

I've tried using mutate in dplyr and transform in RStudio but always receive a similar error. Below is the code I tried using with dplyr.

mature_trees_rev <- mature_trees %>% 
    mutate(plot_type = case_when(Plot.ID(ends_with("D"))~'Decidious',
                                 Plot.ID(ends_with("E"))~'Evergreen',TRUE~"NA"))
mature_trees <- transform(mature_trees, sample_type= ifelse(Plot.ID (endsWith,"D"),"Deciduous", "Evergreen"))
str(mature_trees)
'data.frame':	229 obs. of  8 variables:
 $ Plot.ID   : chr  "0181E" "0181E" "0181E" "0181E" ...
 $ Tag.number: int  1 2 3 4 5 6 7 8 9 10 ...
 $ Species   : chr  "PIAB" "ACRU" "PIAB" "PIAB" ...
 $ Year      : int  2017 2017 2017 2017 2017 2017 2017 2017 2017 2017 ...
 $ D_2017    : num  15.2 25 8.5 11.8 24.5 15 15.7 10 9.3 NA ...
 $ D_2018    : num  15.8 25.9 8.5 11.9 24.7 15.1 15.8 9.9 9.7 12.2 ...
 $ D_2019    : num  15.6 25.9 9.5 12 24.8 15 16.2 10 9.5 15.3 ...

I've tried this with the Plot.ID element as both a factor and character string (with a lot of syntax variations), but always get a similar result. I was able to create a new column using mutate, but not when using any of the existing data.frame conditions. I guess I'm really trying to figure out why the data.frame element (Plot.ID) is being treated as a function? Thanks.

Hi Tom, welcome!

You are using the wrong function, you can't use tidyselect functions to check for text inside variables, try using stringr functions instead, see this example:

library(dplyr)
library(stringr)

mature_trees <- data.frame(stringsAsFactors=FALSE,
           Plot.ID = c("0181E", "0181E", "0181D", "0181D"),
           Tag.number = c(1L, 2L, 3L, 4L),
           Species = c("PIAB", "ACRU", "PIAB", "PIAB"),
           Year = c(2017L, 2017L, 2017L, 2017L),
           D_2017 = c(15.2, 25, 8.5, 11.8),
           D_2018 = c(15.8, 25.9, 8.5, 11.9),
           D_2019 = c(15.6, 25.9, 9.5, 12)
)

mature_trees %>% 
    mutate(plot_type = case_when(str_detect(Plot.ID, "D$")~'Decidious',
                                 str_detect(Plot.ID, "E$")~'Evergreen',
                                 TRUE~"NA"))
#>   Plot.ID Tag.number Species Year D_2017 D_2018 D_2019 plot_type
#> 1   0181E          1    PIAB 2017   15.2   15.8   15.6 Evergreen
#> 2   0181E          2    ACRU 2017   25.0   25.9   25.9 Evergreen
#> 3   0181D          3    PIAB 2017    8.5    8.5    9.5 Decidious
#> 4   0181D          4    PIAB 2017   11.8   11.9   12.0 Decidious

Created on 2019-09-23 by the reprex package (v0.3.0.9000)

Note: For future posts, please provide a proper REPRoducible EXample (reprex) like the shown above.

2 Likes

Hi @trw!

Just chiming in to say that your confusion about ends_with() (the tidyselect function that is meant as a helper for selecting data frame columns inside select() and its relatives) is entirely understandable because there is a base R function called endsWith() that does what you had in mind (determines which elements in a vector of strings end with a specified set of characters). I know, so similar! :dizzy_face:

I suspect this was a case of autocomplete leading you astray, since it may have suggested ends_with() ahead of endsWith() due to you having the tidyverse loaded.

From a novice’s perspective, all this similar-but-different syntax is, frankly, often frustrating. Eventually you get used to it (which mostly means you catch your mistakes faster, not that you make fewer mistakes :laughing:). There’s no real justification for the multiplicity other than that the R ecosystem has evolved over time from many different people making independent contributions. The beauty and the peril of open source software! :upside_down_face:

1 Like

Hi andresrcs - Thanks so much for the quick and helpful response. You were able to produce exactly what I am trying to do. However, when I try to run your code I still get a similar type error message: Error in str_detect(Plot.ID, "D$") : could not find function "str_detect". I get this even if I recreate a new test data.frame from scratch. I wonder if there is something in my original set-up that is causing this issue? Thanks again.

I don't think so, you are getting that error message because either you haven't loaded the stringr package or you don't even have it installed. Do you get any error message if you load the library with library(stringr)?

Hi Andres - That did the trick and I do feel somewhat foolish for laboring away at this as long as I did. Your insight set me straight pretty quickly. The abundant libraries and tricky syntax has been a bit of a struggle as I plow ahead. Thanks again - Tom

Happy to hear you have been able to solve your problem, and don't worry, I'm sure you are going to pass this learning stage pretty soon, we all have being there.

Anyways, if your question's been answered (even by you!), would you mind choosing a solution? It helps other people see which questions still need help, or find solutions if they have similar problems. Here’s how to do it:

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.