8

(並べ替えを含まない関連する質問paste。並べ替える必要がない場合にのみ使用するのは簡単です。)

一般的な「item1」、「item2」などの文字列を含む、理想的とは言えない構造のテーブルがあります。これらの列をアルファベット順にカンマ区切りで連結した新しい文字変数を作成したいと考えています。たとえば、行 5 で、項目 1 = "牛乳"、項目 2 = "卵"、項目 3 = "バター" の場合、行 5 の新しい変数は "バター、卵、牛乳" になる可能性があります。

f()以下に、2 つの文字変数で動作する関数を書きました。しかし、私は問題を抱えています

  • 使用mapplyまたはその他の「ベクトル化」(実際には単なる for ループであることはわかっています)
  • 関数を任意の数の列に一般化する

どんな助けでも大歓迎です。

df <- data.frame(a =c("foo","bar"), 
                 b= c("baz","qux"))   
paste(df$a,df$b, sep=", ")
# returns [1] "foo, baz" "bar, qux" ... but I want [1] "baz, foo" "bar, qux"

f <- function(a,b) paste(c(a,b)[order(c(a,b))],collapse=", ")
f("foo","baz") 
# returns [1] "baz, foo" ... which is what I want ... how to vectorize?

df$new_var <- mapply(f, df$a, df$b)
df 
#     a   b new_var      <- new_var is not what I want
# 1 foo baz    1, 2
# 2 bar qux    1, 2

# Interestingly, data.table is smart enough to fix my bad mapply
library(data.table)
dt <- data.table(a =c("foo","bar"), 
                 b= c("baz","qux"))  
dt[,new_var:=mapply(f, a, b)]
dt
#     a    b  new_var    <- new var IS what I want
# 1: foo baz baz, foo
# 2: bar qux bar, qux
4

2 に答える 2

4

私の最初の考えは、これを行うことでした:

dt[, new_var := paste(sort(.SD), collapse = ", "), by = 1:nrow(dt)]

ただし、いくつかの簡単な変更を加えることで、関数を機能させることができます。

f = function(...) paste(c(...)[order(c(...))],collapse=", ")

dt[, new_var := do.call(function(...) mapply(f, ...), .SD)]
于 2015-02-25T21:51:22.190 に答える