在循环中使用动态文本引用data.table列

时间:2015-06-10 00:46:01

标签: r data.table

我每次选择一个不同的列时会尝试将表绑定到自身上几次,这将取决于我们在循环中的位置,但我无法使其工作。

#create a test data.table
dt<-data.table(start=c(1,1,2,2,3,3,4,4),
           start_2_end=0,
           id=rep(c("A","B")),
           ret1=1:8,
           ret2=9:16,
           ret3=17:24)


#Create table where start = end 
cretdt <- dt[,.(start,
                    end=start,
                    id,
                    start_2_end=0,
                    cret=1)]

#loop and bind onto itself and pull in the correct ret column
for (i in 1:2)
{
  cretdt <- rbind(cretdt,
                     dt[,.(start,
                          end=start+i,
                          id,
                          start_2_end=i,
                          cret=noquote(paste0("ret",(i+1)))
                          )]
                 )
 }

我的问题在于'cret = noquote(paste0(“ret”,(i + 1)))'部分;它只是输入名称“ret2”和“ret3”而不是ret2或ret3列中的相应值。

我已经尝试将cret传递给变量然后使用eval(),但这似乎不起作用。

这有可能实现吗?请帮忙。如果您需要更多详细信息,请与我们联系。

2 个答案:

答案 0 :(得分:1)

您真的在这里寻找重塑操作,但我会展示另一种绕过循环的方法:

s2e = 0:2
dt[,.(
  start = start,
  end   = start+rep(s2e,each=nrow(dt)),
  id    = id,
  s2e   = rep(s2e,each=nrow(dt)),
  cret  = unlist(mget(paste0('ret',s2e+1L)))
)]

给出了

    start end id s2e cret
 1:     1   1  A   0    1
 2:     1   1  B   0    2
 3:     2   2  A   0    3
 4:     2   2  B   0    4
 5:     3   3  A   0    5
 6:     3   3  B   0    6
 7:     4   4  A   0    7
 8:     4   4  B   0    8
 9:     1   2  A   1    9
10:     1   2  B   1   10
11:     2   3  A   1   11
12:     2   3  B   1   12
13:     3   4  A   1   13
14:     3   4  B   1   14
15:     4   5  A   1   15
16:     4   5  B   1   16
17:     1   3  A   2   17
18:     1   3  B   2   18
19:     2   4  A   2   19
20:     2   4  B   2   20
21:     3   5  A   2   21
22:     3   5  B   2   22
23:     4   6  A   2   23
24:     4   6  B   2   24
    start end id s2e cret

(感谢@akrun简化上一学期。我总是忘记mget。)

答案 1 :(得分:0)

您可以使用grepcolnames获取循环每次迭代的列索引:

for (i in 1:2) {
    col.index <- grep(noquote(paste0("ret",(i+1))), colnames(dt))
    cretdt <- rbind(cretdt,
                 dt[,.(start,
                      end=start+i,
                      id,
                      start_2_end=i,
                      cret=col.index
                      )]
             )
}