2017-11-11 10 views
2
library(data.table) 
library(lubridate) 

x1 <- c(20090101, "2009-01-02", "2009 01 03", "2009-1-4", 
     "2009-1, 5", "Created on 2009 1 6", "200901 !!! 07") 

dt2 <- data.table(id = c(1,1,1,2,2,2,2), date1 = ymd(x1), charval = c("aa","vv","ss","a","b","c","d")) 

    id  date1 charval 
1: 1 2009-01-01  aa 
2: 1 2009-01-02  vv 
3: 1 2009-01-03  ss 
4: 2 2009-01-04  a 
5: 2 2009-01-05  b 
6: 2 2009-01-06  c 
7: 2 2009-01-07  d 

私はidでグループ化するための次のコードを使用します。このような何かを得るために特定の機能を使用して1行にR崩壊複数の行

dt3 <- dt2[, Map(function(x,y) ifelse(x != "paste", get(x)(y, na.rm = TRUE), paste(y, sep = ";")), 
           setNames(c("mean", "paste"), names(.SD)), .SD), by = id] 

を:

id  date1 charval 
1: 1 2009-01-02  aa;vv;ss 
2: 2 2009-01-05  a;b;c;d 

実際に私は次の結果を見る:

id date1 charval 
1: 1 NA  aa 
2: 2 NA  a 

1)私は、たとえば次のコードは正常に動作しますので、なぜ平均(DATE1)doesntの仕事 を理解しない)理由をペーストdoesntの仕事 2理解しない:

mean(dt2$date1) 
[1] "2009-01-04" 

答えて

1

我々はMapを通過する必要があり、なぜそれが明確ではありませんおよびget。 OPの質問を約MapあるのでtoStringpaste(..., collapse=', ')

dt2[, .(date1 = mean(date1), charval = paste(charval, collapse=";")), id] 
# id  date1 charval 
#1: 1 2009-01-02 aa;vv;ss 
#2: 2 2009-01-05 a;b;c;d 

です: 'ID' によりグループ化した後、一緒に '日付1' のmeanpaste 'charval'

dt2[, .(date1 = mean(date1), charval = toString(charval)), id] 
# id  date1 charval 
#1: 1 2009-01-02 aa, vv, ss 
#2: 2 2009-01-05 a, b, c, d 

注意を取得getを使用してmeanに電話してください。これがあれば

をトリガしているようだ(!is.numeric(x)の& &!is.complex(x)の& &!is.logical(X)){ 警告( "引数が数値でありませんか、論理:NA」) リターン(NA_real_)

を返すと、それがnumericとして格納されているものの、 『日付1』はクラスDateであると認めるときはNAを返します。 1つのオプションは、envirを指定することですget

もう1つの問題は、ifelseの使用です。そこに2つの要素だけ

dt2[, Map(function(x, y) if(x != "paste") get(x, envir = parent.frame())(y, na.rm = TRUE) 
    else paste(y, collapse=':'), setNames(c("mean", "paste"), names(.SD)), .SD), by = id] 
# id  date1 charval 
#1: 1 2009-01-02 aa:vv:ss 
#2: 2 2009-01-05 a:b:c:d 

getは一種のトリッキーされており、正しい環境を指定した場合

get("mean")(dt2$date1) 
#[1] "2009-01-04" 

またはその代わりのif/elseへの期待通り、それが動作するように、if/elseを使用することをお勧めします"貼り付け"文字列、我々は列classを確認することができますそれがcharacter場合はpasteを行うか、またはmean

を返す
dt2[, Map(function(x, y) if(is.character(y)) get(x)(y, collapse=":") 
    else get(x, envir = parent.frame())(y, na.rm = TRUE), 
    setNames(c("mean", "paste"), names(.SD)), .SD), by = id] 
# id  date1 charval 
#1: 1 2009-01-02 aa:vv:ss 
#2: 2 2009-01-05 a:b:c:d 

第1のアプローチを面倒なく使用する方がよいことに注意してください。

関連する問題