简体   繁体   中英

Pass dynamic column name to transform() R function

I have a data frame with multiple columns and I would like to pass dynamic column names to the R transform() function while running in loop. Request

For example

df1 <- data.frame(col1=c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16),
                  col2=c("id1", "id1", "id1", "id1", "id1", "id1", "id2", "id3", "id3", "id4", "id4", "id4", "id5", "id6", "id7", "id7"), 
                  col3=c(1, 1, 1, 2, 3, 4, 2, 4, 2, 1, 4, 5, 1, 1, 2, 3),
                  col4=c(3, 2, 2, 2, 2, 1, 1, 1, 3, 3, 3, 1, 1, 1, 3, 3))


newColN <- "newCol"
colName <- "col3"

transform(df1, newColN = ~colName)

The second argument to the transform() should take dynamic column names for what ever function I pass.

I tried the following

transform(df1, as.name(newColN) = -(as.name(colName)))

transform(df1, !!newColN := -(!!colName)
+ )

transform(df1, !!as.name(newColN) := -(!!as.name(colName)))

but see an error.

Any suggestion to achieve this efficiently would be appreciated.

transform is not really the right tool to use if that is what you want to do. Suggest that, instead, you use any of these

replace(df1, newColN, -df1[[colName]])

df2 <- df1
df2[[newColN]] <- - df2[[colName]]

within(df1, assign(newColN, - df1[[colName]]))

within(df1, assign(newColN, - get(colName)))

If you don't need to dynamically define the variable on the left hand side then transform can still work:

transform(df1, newCol = - df1[[colName]])

transform(df1, newCol = - environment()[[colName]])

transform(df1, newCol = - get(colName))

You might want to change your transform to mutate in dplyr using which it would be simpler to perform such operations.

library(dplyr)
library(rlang)

df1 %>% mutate(!!newColN := get(colName))

#   col1 col2 col3 col4 newCol
#1     1  id1    1    3      1
#2     2  id1    1    2      1
#3     3  id1    1    2      1
#4     4  id1    2    2      2
#5     5  id1    3    2      3
#6     6  id1    4    1      4
#7     7  id2    2    1      2
#8     8  id3    4    1      4
#9     9  id3    2    3      2
#10   10  id4    1    3      1
#11   11  id4    4    3      4
#12   12  id4    5    1      5
#13   13  id5    1    1      1
#14   14  id6    1    1      1
#15   15  id7    2    3      2
#16   16  id7    3    3      3

Or use sym

df1 %>%  mutate(!!newColN := !!sym(colName))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM