【问题标题】:Learning data.table - how to update values by row number and column name学习 data.table - 如何按行号和列名更新值
【发布时间】:2016-08-09 23:32:31
【问题描述】:

我最近的几篇文章写得不好,所以这次我会尝试做得更好,更干净。

我正在学习如何使用数据表对象,而我正在努力完成的一项任务是同时按行号和列名更新数据表中的值。使用 data.frames 这会容易得多,我只需执行以下操作:

my_df = as.data.frame(matrix(ncol = 10, nrow = (100)))
names(my_df) = c("P1", "P2", "P3", "P4", "P5", "Q1", "Q2", "Q3", "Q4", "Q5")
head(my_df)

  P1 P2 P3 P4 P5 Q1 Q2 Q3 Q4 Q5
1 NA NA NA NA NA NA NA NA NA NA
2 NA NA NA NA NA NA NA NA NA NA
3 NA NA NA NA NA NA NA NA NA NA
4 NA NA NA NA NA NA NA NA NA NA
5 NA NA NA NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA NA NA NA

replacement = c(1, 2, 3, 4, 5)
my_df[2, names(my_df)[1:5]] = replacement
head(my_df)

  P1 P2 P3 P4 P5 Q1 Q2 Q3 Q4 Q5
1 NA NA NA NA NA NA NA NA NA NA
2  1  2  3  4  5 NA NA NA NA NA
3 NA NA NA NA NA NA NA NA NA NA
4 NA NA NA NA NA NA NA NA NA NA
5 NA NA NA NA NA NA NA NA NA NA
6 NA NA NA NA NA NA NA NA NA NA

所以,使用数据框相当容易。但是,我正在努力使用数据表完成同样的任务。对示例数据表使用与上面的数据框相同的结构,我尝试了以下方法:

my_dt = data.table(matrix(ncol = 10, nrow = (100)))
names(my_dt) = c("P1", "P2", "P3", "P4", "P5", "Q1", "Q2", "Q3", "Q4", "Q5")
head(my_dt)

   P1 P2 P3 P4 P5 Q1 Q2 Q3 Q4 Q5
1: NA NA NA NA NA NA NA NA NA NA
2: NA NA NA NA NA NA NA NA NA NA
3: NA NA NA NA NA NA NA NA NA NA
4: NA NA NA NA NA NA NA NA NA NA
5: NA NA NA NA NA NA NA NA NA NA
6: NA NA NA NA NA NA NA NA NA NA

replacement = c(1, 2, 3, 4, 5)
# my_dt[i == 2, names(my_dt)[1:5]] = replacement
# my_dt[i == 2, names(my_dt)[1:5] := replacement]  
# my_dt[2, names(my_dt)[1:5]] = replacement
# my_dt[2, names(my_dt)[1:5] := replacement]  

然而,四个注释行都没有正确替换。感谢您的帮助!

谢谢, 卡诺维斯

【问题讨论】:

  • 可能不是您要查找的内容,但是如何将您的内容写入数据框,然后将其转换为数据表?
  • 我想使用数据表来加速我的代码,性能对于这个项目非常重要。我经常需要访问这个 df / dt 的子集并更新它们的值,我认为访问 dt 的子集比访问 df 的子集要快。所以这就是为什么我不想写入数据框
  • 你不应该需要这个。你这样做让我怀疑你应该使用稀疏矩阵而不是 data.table。

标签: r data.table


【解决方案1】:

或者你可以这样做:

x <- names(my_dt)[1:5]

my_dt[, (x) := lapply(.SD, as.numeric), .SDcols = x]

my_dt[2,  (x):= as.list(replacement)]

首先我们将my_dt 中的目标列转换为numeric.SDcols 表示.SD 中我们感兴趣的列的子集。.SD 包含data.table 中的所有列(by 中使用的列除外)。

将目标列转换为数字后,我们会通过引用更新值。

注意:不必事先定义 x,一切都可以即时完成。但是,如果您定义x,则需要将其包装在() 中以确保data.table 不会查找x

【讨论】:

  • 是的,谢谢!,我喜欢这个和 mkt 的解决方案,但会使用你的,因为我用 NA 初始化并在我的数据表中跟踪 NA 很重要。谢谢
  • 上次跟进,再次感谢。我可以一次通过引用多行来更新值吗?例如,如果我想用替换对象更新行 2:5、列 (x)?我可以!好的,再次感谢
【解决方案2】:

对您的示例进行了一些小的更改,但这有效:

#Filled data.table with integers instead of NAs to avoid converting 
#from logical later
#Left out names as it wasn't relevant to the example
my_dt = as.data.table(matrix(ncol = 10, nrow = (100), 1L))
head(my_dt)

replacement <- 1:5
#Loop through columns and use set to replace values without making a copy
for(k in 1:5) set(my_dt, i = 2L, j = k , value = replacement[k])
head(my_dt)

【讨论】:

  • 谢谢!。你认为问题可能出在我用所有 NA 初始化我的数据框吗?
  • 不,这不是唯一的问题。我这样做主要是为了方便我的回复(不清楚 NA 在您的示例中是否重要)。您的代码还尝试将所有 5 个替换值分配给每个行和列元素。
猜你喜欢
  • 2022-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-02
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多