我想应用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语法的新手,所以可能是一个愚蠢的错误。我们对此表示任何帮助。
答案 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
的新手来说,这是相当高级的东西。但是,这是其他三个变体:
set()
这些方法仅更新相应列向量中的受影响元素,而到目前为止发布的其他解决方案(Frank's,Dan Y's)替换了整个列。如果只需要替换几个元素,则可能会提高性能。
请注意,我们正在使用OP提供的limitlist
。
# 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
# 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
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])
}