long-time lurker, first-time poster.
I'm trying to edit an existing script so that I can use a variable to easily change some of the options in my analysis in order to conduct a sensitivity analysis. In this specific example, I'm trying to use an object so that I can easily change which column I'm calling. The columns contain categorical plant traits, and if a plant has two traits, I split its value between both of those traits.
Here is some example data (note that NumTraits gets derived earlier based on which Trait column I want to use, in this example it is Trait1):
Plant Number | Value | Trait1 | Trait2 | NumTraits |
---|---|---|---|---|
1 | 10 | A | A | 1 |
2 | 20 | B | A B | 1 |
3 | 15 | A B | A B | 2 |
4 | 10 | B | B | 1 |
My existing code reads:
split.data <- data %>%
mutate(NewValue = Value/NumTraits) %>%
tidyr::separate_rows(Trait1, sep = "[ ]") %>%
group_by(Trait1) %>%
summarise(NewValue = sum(Value), .groups = 'drop')
This produces the desired output, which is:
| PlantNumber | Value | Trait1 | Trait2 | NumTraits | | ----------- | ----- | ------ | ------ | --------- | | 1 | 10 | A | A | 1 | | 2 | 20 | B | A B | 1 | | 3 | 7.5 | A | A B | 2 | | 4 | 10 | B | B | 1 | | 3 | 7.5 | B | A B | 2 | (note that normally the two PlantNumber = 3 rows would be adjacent, but for some reason StackOverflow didn't accept that formatting)
I would like to have an object, say trait.to.use <- "Trait1"
, that I can put in place of Trait1 above to easily switch between Trait1 and Trait2 throughout my code. However, if I just replace Trait1 with trait.to.use in the above code, it gives me an error because "trait.to.use" is not a column in my data. I tried trait.to.use[1] and all_of(trait.to.use), but while they return "Trait1" the code doesn't split the values and the resulting Value column is just "Trait1" every line.
How can I pass the column name in an object and get it to produce the desired output? Thanks in advance.
CodePudding user response:
Just use get()
trait.to.use <- "Trait1"
split.data <- data %>%
mutate(NewValue = Value/NumTraits) %>%
tidyr::separate_rows(get(trait.to.use), sep = "[ ]") %>%
group_by(get(trait.to.use)) %>%
summarise(NewValue = sum(Value), .groups = 'drop')
CodePudding user response:
You can use !!sym
to make it symbol
trait.to.use <- c("Trait1" , "Trait2")
data %>%
mutate(NewValue = Value/NumTraits) %>%
tidyr::separate_rows(!!sym(trait.to.use[1]), sep = "[ ]") %>%
group_by(!!sym(trait.to.use[1])) %>%
summarise(NewValue = sum(Value), .groups = 'drop')
- output
# A tibble: 2 × 2
Trait1 NewValue
<chr> <int>
1 A 25
2 B 45
and then you can just change trait.to.use[1]
to trait.to.use[2]