我编写并审查了大量的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(:=)运算符,这使事情稍微更整洁,但每个列名仍必须出现两次,并且该函数对于每个列必须出现一次。
答案 0 :(得分:8)
一种简洁的方法是将输入参数作为数据集('df')的Map
和list
的{{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)]