如果else函数遍历2个向量来操作数据表,则应用

时间:2018-08-23 17:12:33

标签: r data.table

我想应用ifelse函数遍历2个向量,然后根据条件更新数据表的列。我正在寻找一种可以在大量列上工作的解决方案。

我通过玩具数据集class ItemsPage extends React.Component { state = { items: null }; fetchImages = () => axios.get( "https://api.instagram.com/v1/users/self/media/recent/?access_token=" ) .then((result) => this.setState({ items: "test"} ) ); componentDidMount() { this.fetchImages(); } render() { console.log( this.state ); return <div>Test</div>; } } 演示了这个问题。

mtcars

现在,我想限制某些列的值,并用定义的限制替换相应列的值。但是下面的代码给了我奇怪的结果。

library(data.table)
mtcars <- data.table(mtcars)

我想要的输出:

limitlist <- list(c("hp", 300), c("disp", 450.0))
cols <- sapply(limitlist, "[[", 1)
lims <- sapply(limitlist, "[[", 2)
for (i in length(limitlist)) mtcars[, c(cols) := lapply(.SD, function(x){ifelse(x[i] > lims[i], lims[i], x[i])}), .SDcols = cols]

我是data.table语法的新手,所以可能是一个愚蠢的错误。我们对此表示任何帮助。

3 个答案:

答案 0 :(得分:2)

由于Dan的答案不使用data.table语法...

library(data.table)

# input
mylist = list(hp = 300, disp = 450)
DT = data.table(mtcars)

# update
DT[, names(mylist) := Map(pmin, .SD, mylist), .SDcols=names(mylist)]

答案 1 :(得分:2)

对于data.table的新手来说,这是相当高级的东西。但是,这是其他三个变体:

  1. 子集和更新
  2. 更新加入
  3. 使用set()

这些方法仅更新相应列向量中的受影响元素,而到目前为止发布的其他解决方案(Frank'sDan Y's)替换了整个列。如果只需要替换几个元素,则可能会提高性能。

请注意,我们正在使用OP提供的limitlist

1。子集和更新

# subsetting and updating
library(data.table)
DT <- data.table(mtcars)
limitlist <- list(c("hp", 300), c("disp", 450.0))
cols <- sapply(limitlist, "[[", 1)
lims <- as.numeric(sapply(limitlist, "[[", 2))
for (i in seq_along(limitlist))
  DT[get(cols[i]) > lims[i], (cols[i]) := lims[i]]
# check ressults
sapply(cols, function(x) {cbind(max(mtcars[, x]), max(DT[[x]]))})
      hp disp
[1,] 335  472
[2,] 300  450

2。更新加入

# update join
library(data.table)
DT <- data.table(mtcars)
limitlist <- list(c("hp", 300), c("disp", 450.0))
cols <- sapply(limitlist, "[[", 1)
lims <- as.numeric(sapply(limitlist, "[[", 2))
for (i in seq_along(limitlist))
  DT[.(lims[i]), on = sprintf("%s>%s", cols[i], "V1"), (cols[i]) := lims[i]]
# check results
sapply(cols, function(x) {cbind(max(mtcars[, x]), max(DT[[x]]))})
      hp disp
[1,] 335  472
[2,] 300  450

3。使用set()

# using `set()`
library(data.table)
DT <- data.table(mtcars)
limitlist <- list(c("hp", 300), c("disp", 450.0))
cols <- sapply(limitlist, "[[", 1)
lims <- as.numeric(sapply(limitlist, "[[", 2))
for (i in seq_along(limitlist))
  set(DT, which(DT[[cols[i]]] > lims[i]), cols[i], lims[i])
# check results
sapply(cols, function(x) {cbind(max(mtcars[, x]), max(DT[[x]]))})
      hp disp
[1,] 335  472
[2,] 300  450

恕我直言,这种变体是最直接的方法。

答案 2 :(得分:0)

这应该做到:

首先,让您的限制列表成为数字形式,而不是字符形式:

lims <- as.numeric(sapply(limitlist, "[[", 2))

然后您可以循环:

for (i in 1:length(limitlist)) {
    mtcars[[cols[i]]] <- pmin(mtcars[[cols[i]]], lims[i])
}