使用每列使用不同参数的函数转换多列

时间:2019-08-16 04:55:41

标签: r dataframe data.table

我编写并审查了大量的R代码,如下所示:

df <- data.frame(replicate(10, sample(0:5, 10, rep = TRUE)))
my.func <- function(col, y) {col %in% y}

df$X2 <- my.func(df$X2, c(1,2))
df$X3 <- my.func(df$X3, c(4,5))
df$X5 <- my.func(df$X5, c(1,2))
df$X6 <- my.func(df$X6, c(4,5))
df$X8 <- my.func(df$X8, c(4,5))
df$X9 <- my.func(df$X9, c(1,2))
df$X10 <- my.func(df$X10, c(1))

也就是说,使用函数转换data.frame(或data.table)中的某些列,其中一个参数是一列,另一个参数是某个任意的,对该列而言有点唯一的值。 / p>

进行此类转换的更简洁的方法是什么?

我尝试使用data.table的set(:=)运算符,这使事情稍微更整洁,但每个列名仍必须出现两次,并且该函数对于每个列必须出现一次。

2 个答案:

答案 0 :(得分:8)

一种简洁的方法是将输入参数作为数据集('df')的Maplist的{​​{1}}作为参数传递给vector 。此处,data.frame的每一列都是my.func,并且类似地是unit的向量元素。

list

注意:未提供OP的功能或最小的可复制示例,因此未经测试

注意2:在这里,假设列数为3。如果超过3,则也要增加df[] <- Map(my.func, df, list(1:2, 4:5, 3:4)) 的长度


以上内容也可以转换为list语法

data.table

如果仅需要更改列的子集,请在library(data.table) setDT(df)[, names(df) := Map(my.func, .SD, list(1:2, 4:5, 3:4))] 中指定列,然后将.SDcols更改为名称的子集


或与names(df)

tidyverse

答案 1 :(得分:1)

OP的评论请求:

  

使这些列的列名和函数参数之间的关联更明确

调整其他答案中看到的Map方法:

yL <- list(X2 = 1:2, X3 = 4:5, X5 = 3:4, X6 = 4:5, X8 = 4:5, X9 = 1:2, X10 = 1)
df[names(yL)] <-  Map(my.func, df[names(yL)], y = yL)

带有data.table:

# this saves you from writing DT twice
DT[, names(yL) := Map(my.func, .SD, y = yL), .SDcols=names(yL)]