我有一个data.table
,它有几个列(可以是动态的列数),我想对它们应用最小值,每列都有自己的最小值。data.table
的基本版本如下所示:
library(data.table)
dt <- data.table(
urn = 1:10,
col1 = 5:14,
col2 = 11:20
)
- 注意:我只包含了两列,列中的值需要为reprex的最小值。可能会有更多列,因此尝试稍微动态地编写代码。*
我的方法是嵌套lapply
语句等等,但是我不知道如何在lapply
函数中调用我的列。
min_vals <- c(10, 15)
my_cols <- grep("^col", colnames(dt), value = TRUE)
## First approach
dt[,
(my_cols) := lapply(min_vals, function(x) {
my_cols[my_cols < x] <- x
})]
## Second Approach
dt[,
(my_cols) := lapply(min_vals, function(x) {
ifelse(my_cols < x, x, my_cols)
})]
目前,第一种方法将所有行设置为各自的min_vals
,而不仅仅是min_vals
以下的值,第二种方法根本不起作用,而是错误。
所需的输出如下所示:
dt
# urn col1 col2
# <int> <int> <int>
# 1: 1 10 15
# 2: 2 10 15
# 3: 3 10 15
# 4: 4 10 15
# 5: 5 10 15
# 6: 6 10 16
# 7: 7 11 17
# 8: 8 12 18
# 9: 9 13 19
# 10: 10 14 20
如果有一个解决方案允许动态地对与col<number>
匹配的列进行编号,那就太好了。
4条答案
按热度按时间lkaoscv71#
这里你实际上是在尝试同时循环两个列表/向量,而lapply并不适合这样做,所以
mapply
在这里会很有用:为了确保只对所需的列应用函数,还需要告诉它对数据进行子集化,以便只保留所需的列(
.SD
是包含my_cols
中列的数据子集)。cxfofazt2#
我们可以使用
Map
代替lapply
,正如@罗兰在注解中指出的那样,i)在.SD
上循环作为第一个输入(用mycols
指定.SDcols
),ii)使用更快的fielse
代替ifelse
。数据来自OP
创建于2023年3月20日,使用reprex v2.0.2
n3schb8v3#
另一种方法是使用
set()
:输出:
jexiocij4#
使用 forloop: