学习data.table - 如何按行号和列名更新值

时间:2016-08-09 15:00:29

标签: r data.table

我的最后几篇文章写得不好,所以这次我会尝试做一份更好,更清洁的工作。

我正在学习如何使用数据表对象,我正在努力解决的一项任务是同时按行号和列名更新数据表中的值。使用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]  

然而,四条评论行中没有一条做出正确的替换。感谢任何帮助!

谢谢, Canovice

2 个答案:

答案 0 :(得分:7)

或者你可以这样做:

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

答案 1 :(得分:4)

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

#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)