6

次のデータがあります。

library(data.table)
d = data.table(a = c(1:3), b = c(2:4))

そして、この結果を取得したいと思います(任意の数の列で機能する方法で):

d[, c := paste0('a_', a, '_b_', b)]
d
#   a b       c
#1: 1 2 a_1_b_2
#2: 2 3 a_2_b_3
#3: 3 4 a_3_b_4

以下はうまくいきますが、もっと短くて読みやすいものを見つけたいと思っています。

d = data.table(a = c(1:3), b = c(2:4))
d[, c := apply(mapply(paste, names(.SD), .SD, MoreArgs = list(sep = "_")),
               1, paste, collapse = "_")]
4

3 に答える 3

3

片道、ほんの少しきれいに:

d[, c :=  apply(d, 1, function(x) paste(names(d), x, sep="_", collapse="_")) ]

     a b       c
1: 1 2 a_1_b_2
2: 2 3 a_2_b_3
3: 3 4 a_3_b_4
于 2013-07-02T19:59:15.420 に答える
2

これは を使用したアプローチですが、 へdo.call('paste')の単一の呼び出しのみが必要ですpaste

列が整数である状況でベンチマークします(これはより賢明なテストケースのようです)

N <- 1e4

d <- setnames(as.data.table(replicate(5, sample(N), simplify = FALSE)), letters[seq_len(5)])

f5 <- function(d){
  l <- length(d)
  o <- c(1L, l + 1L) + rep_len(seq_len(l) -1L, 2L * l)
  do.call('paste',c((c(as.list(names(d)),d))[o],sep='_'))}


microbenchmark(f1(d), f2(d),f5(d))
Unit: milliseconds
  expr       min        lq    median        uq       max neval
 f1(d)  41.51040  43.88348  44.60718  45.29426  52.83682   100
 f2(d) 193.94656 207.20362 210.88062 216.31977 252.11668   100
 f5(d)  30.73359  31.80593  32.09787  32.64103  45.68245   100
于 2013-07-03T00:50:54.820 に答える
1

行のループを避けるために、これを使用できます。

do.call(paste, c(lapply(names(d), function(n)paste0(n,"_",d[[n]])), sep="_"))

ベンチマーク:

N <- 1e4

d <- data.table(a=runif(N),b=runif(N),c=runif(N),d=runif(N),e=runif(N))

f1 <- function(d)
{
    do.call(paste, c(lapply(names(d), function(n)paste0(n,"_",d[[n]])), sep="_"))
}

f2 <- function(d)
{
    apply(d, 1, function(x) paste(names(d), x, sep="_", collapse="_"))
}

require(microbenchmark)

microbenchmark(f1(d), f2(d))

注:f2@Ricardoの回答に触発されました。

結果:

Unit: milliseconds
  expr      min       lq   median       uq      max neval
 f1(d) 195.8832 213.5017 216.3817 225.4292 254.3549   100
 f2(d) 418.3302 442.0676 451.0714 467.5824 567.7051   100

編集注: での以前のベンチマークでN <- 1e3は、時間に大きな違いは見られませんでした。ありがとう@eddi。

于 2013-07-02T20:18:33.537 に答える