1

I have a data frame that I exported from lightroom to R. In this data frame there is a grading system for the photographs where each is graded with stars from 1 (*) to 5 (*****) I want to replace these stars with numbers but tried several functions (gsub, replace) with no success

Lightroom$Rating <- gsub("*", "1", Lightroom$Rating)

Lightroom <- replace(Lightroom, "*", "1")

Thank you for your help

Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
  • 6
    Maybe `nchar(Lightroom$Rating)` – Darren Tsai Apr 29 '22 at 17:32
  • 2
    fyi, `"*"` is meaningful in regex, it means *"0 or more of the previous character/class/group"*. If you mean the literal `"*"` (as I think you do here), you need to use either `"\\*"` or add the `fixed=TRUE` argument. See https://stackoverflow.com/a/22944075/3358272 for good regex information. I think DarrenTsai's suggestion is likely more appropriate, assuming that your strings and data are perfectly formed/structured. – r2evans Apr 29 '22 at 17:45
  • You would also do well to read the help documentation with functions that do not behave correctly. For instance, `?replace` will tell you that the first argument `x=` is a vector (not a frame) and the second `list=` is an index vector (meaning *integers*), neither of which work with your call. – r2evans Apr 29 '22 at 17:47

2 Answers2

0

If I understand your question correctly, you want to replace the number of stars with the actual count. This allows some flexibility in case you want to do something else with each matched number of asterisks (*).

library(tidyverse)

Lightroom <- data.frame(Rating = c("*",
                                   "**",
                                   "***",
                                   "****",
                                   "*****"))
Lightroom_subbed <- Lightroom %>% 
  mutate(Rating2 = case_when(grepl(x = Rating, pattern = "^\\*{1}$") ~ "1",
                             grepl(x = Rating, pattern = "^\\*{2}$") ~ "2",
                             grepl(x = Rating, pattern = "^\\*{3}$") ~ "3",
                             grepl(x = Rating, pattern = "^\\*{4}$") ~ "4",
                             grepl(x = Rating, pattern = "^\\*{5}$") ~ "5"
  )
  )
Lightroom_subbed
 Rating Rating2
1      *       1
2     **       2
3    ***       3
4   ****       4
5  *****       5
TheSciGuy
  • 1,154
  • 11
  • 22
  • 1
    If you're going to go down the road of looking for explicit strings, I think a faster solution would be to create `stars <- data.frame(Rating=c("*","**",'***",...), Rating2=1:5)` and `left_join(., stars, by = "Rating")`. It should be must faster. – r2evans Apr 29 '22 at 17:48
  • I don't think speed is going to be an issue, but I like the approach. – TheSciGuy Apr 29 '22 at 17:53
  • 1
    Also, valid point. I don't think the OP understood how to escape special characters in regex, so figured it would be useful to show how that's done. – TheSciGuy Apr 29 '22 at 17:55
0

Much simpler approach is available. Use the factor data-type's underlying integer structure:

as.numeric(factor(Lightroom$Rating))
[1] 1 2 3 4 5
IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • Thank you! that worked beautifully but for some reason when I apply it to the data frame itself it reduces 1 from each value - ***** turn to 4. Any idea why? – Yaly Mevorach Apr 30 '22 at 06:12
  • Show us ‘table’ applied to that column. I’m guessing there aren’t any “*” entries – IRTFM Apr 30 '22 at 13:30