将多个字符列转换为 R 数据框中的表达式
Converting multiple character columns to expressions in R dataframe
我有一个数据框:
Column1 | Column2 | Column3 | Calc1 | Calc2 |
1 | 2 | 4 | Column1 + Column2 | Column3 + Column1 |
7 | 6 | 3 | Column1 + Column2 | Column3 + Column1 |
9 | 9 | 10 | Column1 + Column2 | Column3 + Column1 |
Column1、Column2、Column3 是“数字”。 Calc1 和 Calc2 是“字符”。
我还有一个名为 ColNameList 的列名列表,其中包含 c("Calc1", "Calc2")。
我想应用一些将字符值转换为实际 R 表达式的函数。我希望此函数应用于的列必须由列名列表通知(即检查 ColNameList 中的列名列表,然后将这些列名与数据框中的列匹配,然后应用函数将字符转换为表达式。)
我的预期输出是这样的:
Column1 | Column2 | Column3 | Calc1 | Calc2 |
1 | 2 | 4 | 3 | 5 |
7 | 6 | 3 | 13 | 10 |
9 | 9 | 10 | 18 | 19 |
我试过:
df1 <- df1(apply(df1[,ColNameList],2, function(x) eval(parse(text=df1$x))))
我环顾四周并发现了类似的问题,但我似乎无法对其他解决方案进行逆向工程以适应我的情况;特别是要求该函数仅适用于 ColNameList 中列出的列。
在 data.table 中它可以正常工作:
library(data.table)
setdT(df)
df[, c1 := eval(parse(text = Calc1))]
如果您同时想要两者,那么:
a[, `:=` (c1 = eval(parse(text = Calc1)), c2 = eval(parse(text = Calc2)))]
使用 eval
+ str2expression
的基础 R 选项
transform(
df,
Calc1 = eval(str2expression(Calc1)),
Calc2 = eval(str2expression(Calc2))
)
给予
Column1 Column2 Column3 Calc1 Calc2
1 1 2 4 3 5
2 7 6 3 13 10
3 9 9 10 18 19
更新
如果您有一个要应用于列的函数 f
,这里可能是一个选项。假设 f
给出如下
f <- function(x, y) x + y^2
当我们运行
as.data.table(df)[
,
c(cols) := lapply(
.SD[, cols, with = FALSE],
function(x) {
do.call(
f,
unname(.SD[, unlist(strsplit(unique(x), "\s\+\s")), with = FALSE])
)
}
)
][]
我们会得到
Column1 Column2 Column3 Calc1 Calc2
1: 1 2 4 5 5
2: 7 6 3 43 52
3: 9 9 10 90 91
我找到了一个解决方案,它接受列名列表,并使用它来识别给定数据框中的列,然后将给定列中的字符值转换为实际的 R 表达式。此解决方案很有用,因为它可以泛化为接受不同的表达式,而不仅仅是求和。
解决方法如下:
Column1 <- c(1,7,9)
Column2 <- c(2,6,9)
Column3 <- c(4,3,10)
Calc1 <- c("Column1 + Column2", "Column1 + Column2", "Column1 + Column2")
Calc2 <- c("Column3 + Column1", "Column3 + Column1", "Column3 + Column1")
df <- data.frame(Column1,Column2,Column3,Calc1,Calc2)
ColNameList <- c("Calc1", "Calc2")
df2 <- df %>%
mutate(across(ColNameList, ~ eval(str2expression(.))))
我有一个数据框:
Column1 | Column2 | Column3 | Calc1 | Calc2 |
1 | 2 | 4 | Column1 + Column2 | Column3 + Column1 |
7 | 6 | 3 | Column1 + Column2 | Column3 + Column1 |
9 | 9 | 10 | Column1 + Column2 | Column3 + Column1 |
Column1、Column2、Column3 是“数字”。 Calc1 和 Calc2 是“字符”。
我还有一个名为 ColNameList 的列名列表,其中包含 c("Calc1", "Calc2")。
我想应用一些将字符值转换为实际 R 表达式的函数。我希望此函数应用于的列必须由列名列表通知(即检查 ColNameList 中的列名列表,然后将这些列名与数据框中的列匹配,然后应用函数将字符转换为表达式。)
我的预期输出是这样的:
Column1 | Column2 | Column3 | Calc1 | Calc2 |
1 | 2 | 4 | 3 | 5 |
7 | 6 | 3 | 13 | 10 |
9 | 9 | 10 | 18 | 19 |
我试过:
df1 <- df1(apply(df1[,ColNameList],2, function(x) eval(parse(text=df1$x))))
我环顾四周并发现了类似的问题,但我似乎无法对其他解决方案进行逆向工程以适应我的情况;特别是要求该函数仅适用于 ColNameList 中列出的列。
在 data.table 中它可以正常工作:
library(data.table)
setdT(df)
df[, c1 := eval(parse(text = Calc1))]
如果您同时想要两者,那么:
a[, `:=` (c1 = eval(parse(text = Calc1)), c2 = eval(parse(text = Calc2)))]
使用 eval
+ str2expression
transform(
df,
Calc1 = eval(str2expression(Calc1)),
Calc2 = eval(str2expression(Calc2))
)
给予
Column1 Column2 Column3 Calc1 Calc2
1 1 2 4 3 5
2 7 6 3 13 10
3 9 9 10 18 19
更新
如果您有一个要应用于列的函数 f
,这里可能是一个选项。假设 f
给出如下
f <- function(x, y) x + y^2
当我们运行
as.data.table(df)[
,
c(cols) := lapply(
.SD[, cols, with = FALSE],
function(x) {
do.call(
f,
unname(.SD[, unlist(strsplit(unique(x), "\s\+\s")), with = FALSE])
)
}
)
][]
我们会得到
Column1 Column2 Column3 Calc1 Calc2
1: 1 2 4 5 5
2: 7 6 3 43 52
3: 9 9 10 90 91
我找到了一个解决方案,它接受列名列表,并使用它来识别给定数据框中的列,然后将给定列中的字符值转换为实际的 R 表达式。此解决方案很有用,因为它可以泛化为接受不同的表达式,而不仅仅是求和。
解决方法如下:
Column1 <- c(1,7,9)
Column2 <- c(2,6,9)
Column3 <- c(4,3,10)
Calc1 <- c("Column1 + Column2", "Column1 + Column2", "Column1 + Column2")
Calc2 <- c("Column3 + Column1", "Column3 + Column1", "Column3 + Column1")
df <- data.frame(Column1,Column2,Column3,Calc1,Calc2)
ColNameList <- c("Calc1", "Calc2")
df2 <- df %>%
mutate(across(ColNameList, ~ eval(str2expression(.))))