gpt4 book ai didi

r - 根据另一列的文本,整理 data.table 每行不同列的数据

转载 作者:行者123 更新时间:2023-12-05 00:34:54 26 4
gpt4 key购买 nike

我想向我的 data.table 添加一个新列,其中包含来自其他列之一的数据。但是,列的选择因行而异 - 取决于另一列的内容。所以:

对于数据集:

     a_data b_data column_choice
[1,] 55 1 a
[2,] 56 2 a
[3,] 57 3 b

产生于:
dat=data.table(a_data = c(55, 56, 57), 
b_data = c(1, 2, 3),
column_choice = c("a", "a", "b"))

我想要一个新列“选择”,它包含(每行)来自“a_data”或“b_data”的数据,具体取决于“column_choice”的值。因此,生成的数据表将是:
     a_data b_data column_choice chosen
[1,] 55 1 a 55
[2,] 56 2 a 56
[3,] 57 3 b 3

我设法使用以下方法获得了所需的效果:
dat=dat[, data.table(.SD, chosen=.SD[[paste0(.SD$column_choice, "_data")]]),
by=1:nrow(a)]
dat$nrow = NULL

但是这感觉很笨重;也许有一种更简单的方法来做到这一点(这无疑也会教我一些关于 R 的知识)?

在实践中,数据框还有很多其他的列需要保留,不仅仅是'a 或b' 的更多选择,以及其中几种类型的列要生成,所以我宁愿不使用基本的 ifelse可能适用于上述基本示例的解决方案。

非常感谢您的帮助。

最佳答案

我想我现在找到了一个正确矢量化的一个类轮,在这种情况下,这也比其他答案快。

petesFun2 使用 data.table 聚合作为 petesFun,但是现在跨 column_choice 进行矢量化(而不是像以前那样按项目进行)。

虽然 petesFun2 对我来说很好,但它确实以不同的顺序保留了行和列。因此,为了与其他答案进行比较,我添加了 petesFun2Clean,它与其他答案保持相同的顺序。

petesFun2 <-function(myDat) {
return(myDat[, cbind(.SD, chosen=.SD[[paste0(.BY$column_choice, "_data")]]),
by=column_choice])
}

petesFun2Clean <-function(myDat) {
myDat = copy(myDat) # To prevent reference issues
myDat[, id := seq_len(nrow(myDat))] # Assign an id
result = myDat[, cbind(.SD, chosen=.SD[[.BY$choice]]),
by=list(column_choice, choice=paste0(column_choice, "_data"))]

# recover ordering and column order.
return(result[order(id),
list(a_data, b_data, c_data, column_choice, chosen)])
}

benchmark(benRes<- myFun(test.dat),
petesRes<- petesFun(test.dat),
dowleRes<- dowleFun(test.dat),
petesRes2<-petesFun2(test.dat),
petesRes2Clean<- petesFun2Clean(test.dat),
replications=25,
columns=c("test", "replications", "elapsed", "relative"))

# test replications elapsed relative
# 1 benRes <- myFun(test.dat) 25 0.337 4.160494
# 3 dowleRes <- dowleFun(test.dat) 25 0.191 2.358025
# 5 petesRes2Clean <- petesFun2Clean(test.dat) 25 0.122 1.506173
# 4 petesRes2 <- petesFun2(test.dat) 25 0.081 1.000000
# 2 petesRes <- petesFun(test.dat) 25 4.018 49.604938

identical(petesRes2, benRes)
# FALSE (due to row and column ordering)
identical(petesRes2Clean, benRes)
# TRUE

编辑:我刚刚注意到(正如马修在评论中提到的)我们现在按组:=。所以我们可以删除 cbind 并简单地执行以下操作:

myDat[, 选择 := .SD[[paste0(.BY$column_choice, "_data")]],
by=column_choice]

关于r - 根据另一列的文本,整理 data.table 每行不同列的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10176050/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com