それを適用「splitstackshapeは」このために使用することができることを示し、ここで削除された答えがあります。それはできますが、削除された答えは間違った機能を使用していました。代わりに、listCol_w
関数を使用する必要があります。残念ながら、現在の形式では、この関数は列間でベクトル化されないため、フラット化する必要がある列ごとにlistCol_w
への呼び出しをネストする必要があります。
は、ここでのアプローチです。それ以外の場合は文字にすべての値を強制うfill = NA_character_
に、それはデフォルトで、ためfill = NA
が指定されていることを
library(splitstackshape)
listCol_w(listCol_w(df, "COUNT", fill = NA), "TREAT", fill = NA)
## CAT COUNT_fl_1 COUNT_fl_2 COUNT_fl_3 TREAT_fl_1 TREAT_fl_2 TREAT_fl_3
## 1: A 1 2 3 Treat-a Treat-b NA
## 2: B 4 5 NA Treat-c Treat-d Treat-e
注意。
「data.table」のtranspose
を使用することもできます。ここには実現可能な実装があります(恐ろしいですが、この関数を使うのは簡単です)。利点は、(1)列を指定して平坦化すること、(2)元の列を削除するかどうかを決定できること、(3)高速です。
flatten <- function(indt, cols, drop = FALSE) {
require(data.table)
if (!is.data.table(indt)) indt <- as.data.table(indt)
x <- unlist(indt[, lapply(.SD, function(x) max(lengths(x))), .SDcols = cols])
nams <- paste(rep(cols, x), sequence(x), sep = "_")
indt[, (nams) := unlist(lapply(.SD, transpose), recursive = FALSE), .SDcols = cols]
if (isTRUE(drop)) {
indt[, (nams) := unlist(lapply(.SD, transpose), recursive = FALSE),
.SDcols = cols][, (cols) := NULL]
}
indt[]
}
使用方法
維持元の列:
flatten(df, c("COUNT", "TREAT"))
# CAT COUNT TREAT COUNT_1 COUNT_2 COUNT_3 TREAT_1 TREAT_2 TREAT_3
# 1: A 1,2,3 Treat-a,Treat-b 1 2 3 Treat-a Treat-b NA
# 2: B 4,5 Treat-c,Treat-d,Treat-e 4 5 NA Treat-c Treat-d Treat-e
削除元の列:
flatten(df, c("COUNT", "TREAT"), TRUE)
# CAT COUNT_1 COUNT_2 COUNT_3 TREAT_1 TREAT_2 TREAT_3
# 1: A 1 2 3 Treat-a Treat-b NA
# 2: B 4 5 NA Treat-c Treat-d Treat-e
が提案されている他のソリューションとの比較のためにthis gistを参照してください。
実際のデータの量はどれくらいですか(パフォーマンスに問題がありますか?) – Heroka
splitstackshapeパッケージのcSplit()は良い選択です。 – jazzurro
あなたの例 'df [2:3] < - lapply(df [、2:3]、function(x)do.call(rbind、lapply(x、" ["、1:3)))'のようですいいスタート – nicola