r data.table通过引用其他列中的值添加新列和值

发布于 2025-01-17 11:12:41 字数 1247 浏览 0 评论 0原文

我有一个示例 data.table 如下:

> dt = data.table("Label" = rep(LETTERS[1:3], 3),
+                 "Col_A" = c(2,3,5,0,2,7,6,8,9),
+                 "Col_B" = c(1,4,3,5,2,0,7,5,8),
+                 "Col_C" = c(2,0,4,1,5,6,7,3,0))
> dt[order(Label)]

 Label Col_A Col_B Col_C
1:     A     2     1     2
2:     A     0     5     1
3:     A     6     7     7
4:     B     3     4     0
5:     B     2     2     5
6:     B     8     5     3
7:     C     5     3     4
8:     C     7     0     6
9:     C     9     8     0

我想创建一个新列,它根据 Label 列从现有列中获取值。我想要的示例输出如下:

 Label Col_A Col_B Col_C Newcol
1:     A     2     1     2      2
2:     A     0     5     1      0
3:     A     6     7     7      6
4:     B     3     4     0      4
5:     B     2     2     5      2
6:     B     8     5     3      5
7:     C     5     3     4      4
8:     C     7     0     6      6
9:     C     9     8     0      0

逻辑是 Newcol 值引用基于 Label 列的相应列。例如,Label 列的前 3 行是 A,因此 Newcol 列的前 3 行指的是前 3 行Col_A 列的。

我尝试使用代码 dt[, `:=` ("Newcol" = eval(as.symbol(paste0("Col_", dt$Label))))] 但它没有给出所需的输出。

I have a sample data.table as below:

> dt = data.table("Label" = rep(LETTERS[1:3], 3),
+                 "Col_A" = c(2,3,5,0,2,7,6,8,9),
+                 "Col_B" = c(1,4,3,5,2,0,7,5,8),
+                 "Col_C" = c(2,0,4,1,5,6,7,3,0))
> dt[order(Label)]

 Label Col_A Col_B Col_C
1:     A     2     1     2
2:     A     0     5     1
3:     A     6     7     7
4:     B     3     4     0
5:     B     2     2     5
6:     B     8     5     3
7:     C     5     3     4
8:     C     7     0     6
9:     C     9     8     0

I want to create a new column which takes values from the existing columns based on the Label column. My desired sample output is as below:

 Label Col_A Col_B Col_C Newcol
1:     A     2     1     2      2
2:     A     0     5     1      0
3:     A     6     7     7      6
4:     B     3     4     0      4
5:     B     2     2     5      2
6:     B     8     5     3      5
7:     C     5     3     4      4
8:     C     7     0     6      6
9:     C     9     8     0      0

The logic is that the Newcol value refers to the respective columns based on the Label column. For example, the first 3 rows of the Label column is A, so the first 3 rows of the Newcol column refers to the first 3 rows of the Col_A column.

I have tried using the code dt[, `:=` ("Newcol" = eval(as.symbol(paste0("Col_", dt$Label))))] but it doesn't give the desired output.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

日记撕了你也走了 2025-01-24 11:12:41

使用fcase

cols <- unique(dt$Label)
dt[,newCol:=eval(parse(text=paste('fcase(',paste0("Label=='",cols,"',Col_",cols,collapse=','),')')))][]

    Label Col_A Col_B Col_C newCol
   <char> <num> <num> <num>  <num>
1:      A     2     1     2      2
2:      B     3     4     0      4
3:      C     5     3     4      4
4:      A     0     5     1      0
5:      B     2     2     5      2
6:      C     7     0     6      6
7:      A     6     7     7      6
8:      B     8     5     3      5
9:      C     9     8     0      0

With fcase:

cols <- unique(dt$Label)
dt[,newCol:=eval(parse(text=paste('fcase(',paste0("Label=='",cols,"',Col_",cols,collapse=','),')')))][]

    Label Col_A Col_B Col_C newCol
   <char> <num> <num> <num>  <num>
1:      A     2     1     2      2
2:      B     3     4     0      4
3:      C     5     3     4      4
4:      A     0     5     1      0
5:      B     2     2     5      2
6:      C     7     0     6      6
7:      A     6     7     7      6
8:      B     8     5     3      5
9:      C     9     8     0      0
满地尘埃落定 2025-01-24 11:12:41

我们可以使用 kit 包的矢量化 switch 函数,它像 data.table 一样是 fastverse 的一部分。

dt[, "Newcol" := kit::vswitch(Label, c("A", "B", "C"), list(Col_A, Col_B, Col_C))]

# or if you want to pass column indices
dt[, "Newcol" := kit::vswitch(Label, c("A", "B", "C"), dt[,2:4])]

dt
   Label Col_A Col_B Col_C Newcol
1:     A     2     1     2      2
2:     A     0     5     1      0
3:     A     6     7     7      6
4:     B     3     4     0      4
5:     B     2     2     5      2
6:     B     8     5     3      5
7:     C     5     3     4      4
8:     C     7     0     6      6
9:     C     9     8     0      0

We can use a vectorized switch function of the kit package, which like data.table is part of the fastverse.

dt[, "Newcol" := kit::vswitch(Label, c("A", "B", "C"), list(Col_A, Col_B, Col_C))]

# or if you want to pass column indices
dt[, "Newcol" := kit::vswitch(Label, c("A", "B", "C"), dt[,2:4])]

dt
   Label Col_A Col_B Col_C Newcol
1:     A     2     1     2      2
2:     A     0     5     1      0
3:     A     6     7     7      6
4:     B     3     4     0      4
5:     B     2     2     5      2
6:     B     8     5     3      5
7:     C     5     3     4      4
8:     C     7     0     6      6
9:     C     9     8     0      0
风铃鹿 2025-01-24 11:12:41
library(data.table)
dt = data.table("Label" = rep(LETTERS[1:3], 3),
                "Col_A" = c(2,3,5,0,2,7,6,8,9),
                "Col_B" = c(1,4,3,5,2,0,7,5,8),
                "Col_C" = c(2,0,4,1,5,6,7,3,0))

dt[, new := ifelse(Label == "A", Col_A, NA)]
dt[, new := ifelse(Label == "B", Col_B, new)]
dt[, new := ifelse(Label == "C", Col_C, new)]
library(data.table)
dt = data.table("Label" = rep(LETTERS[1:3], 3),
                "Col_A" = c(2,3,5,0,2,7,6,8,9),
                "Col_B" = c(1,4,3,5,2,0,7,5,8),
                "Col_C" = c(2,0,4,1,5,6,7,3,0))

dt[, new := ifelse(Label == "A", Col_A, NA)]
dt[, new := ifelse(Label == "B", Col_B, new)]
dt[, new := ifelse(Label == "C", Col_C, new)]
泪冰清 2025-01-24 11:12:41

如果您能够使用 dplyr 库,我会使用那里的 case_when 函数。

dt$newCol <- case_when(dt$Col_A == 'A' ~ Col_A, dt$Col_A == 'B' ~ Col_B, dt$Col_A == 'C' ~ Col_C)

我没有测试过该代码,但它会是类似的东西。

If you are able to use the dplyr library, I would use the case_when function from there.

dt$newCol <- case_when(dt$Col_A == 'A' ~ Col_A, dt$Col_A == 'B' ~ Col_B, dt$Col_A == 'C' ~ Col_C)

I've not tested that code but it would be something like that.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文