0

Provided that here there is written that I can pass {{colname}} to mutate, where colname is a variable that contains a column name, I cannot figure out why this code doesn't work:

testdf <- data.frame(a=c("Hello", "Hi", "Howy"))
varname <- "a"
testdf %>% mutate(b=nchar({{varname}}))

It returns the number of characters in the letter a:

      a b
1 Hello 1
2    Hi 1
3  Howy 1

How can I count the number of characters in a column and assign the value to another column, when the name of the first column is saved into a variable?

1
  • Does mutate(b=nchar(!!sym(varname))) give the expected result? Commented Nov 5, 2024 at 19:00

3 Answers 3

1

The issue arises because {{varname}} doesn't evaluate to the content of the variable varname when you use it inside mutate().

In this case, {{varname}} is treated literally, which is why you're only seeing 1 for each row.

To solve this, you can simply use base R for a straightforward solution. Here’s how you can do it:

# Create a data frame
testdf <- data.frame(a = c("Hello", "Hi", "Howy"))

# Variable storing column name
varname <- "a"

# Use base R to add a column `b` with character counts
testdf$b <- nchar(testdf[[varname]])

OUTPUT

      a  b
1 Hello  5
2    Hi  2
3  Howy  4
  • testdf[[varname]] retrieves the column specified by varname from testdf.
  • nchar(testdf[[varname]]) counts the characters in each element of that column.
  • testdf$b <- ... assigns these counts to a new column b in testdf.
Sign up to request clarification or add additional context in comments.

3 Comments

"The issue arises because {{varname}} doesn't evaluate to the content of the variable varname when you use it inside mutate().". That's not how I understood it. here there is written that I can pass {{colname}} to mutate, where colname is a variable that contains a column name.
To make {{ }} work, you need to convert the column name string ("a") to an unquoted symbol. This can be done with rlang::sym():
library(dplyr) library(rlang) testdf <- testdf %>% mutate(b = nchar({{ sym(varname) }}))
1

As varname is a character you can use the .data pro-noun:

testdf <- data.frame(a = c("Hello", "Hi", "Howy"))
varname <- "a"

library(dplyr, warn = FALSE)

testdf %>%
  mutate(b = nchar(.data[[varname]]))
#>       a b
#> 1 Hello 5
#> 2    Hi 2
#> 3  Howy 4

2 Comments

Isn't my code supposed to work? here there is written that I can pass {{colname}} to mutate, where colname is a variable that contains a column name.
Nop. In the referenced post the function is called with an unquoted variable, i.e. meanofcol(iris, Petal.Width). But when you pass the column name as a character vector, e.g. meanofcol(iris, "Petal.Width") you should use the .data pronoun. See the Programming with dplyr vignette.
1

As it is designed like

library(dplyr)
f = \(dd, var) mutate(dd, b = nchar( {{var}} ))

giving

> f(testdf, a) # no quotes
      a b
1 Hello 5
2    Hi 2
3  Howy 4

As user @AndreWildberg points out in a comment, you will need to swap to

f2 = \(dd, var) mutate(dd, b = nchar( !!sym(var) ))

giving

> f2(testdf, "a") # quotes
      a b
1 Hello 5
2    Hi 2
3  Howy 4

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.