2015-05-13 20 views
8

numaralı sütunu bırakıyor. Sütun içeriğini bir ayırıcı ile bölme ve bir tabloyu uzun bir formata dönüştürmenin bir yolunu arıyordum.paketinden cSplit ürününü buldum ve neredeyse aradığım şeyi yapıyor.cSplit kitaplığı (splitstackshape) her zaman

drop ile ilgili bir sorun bulunmamaktadır. Bölünmüş sütunumun bir şekilde kopyalanmasını bekledim, ancak bu gerçekleşmiyor. Yanlış mı yapıyorum? Biri sorunu yaşadı mı?

Yanlış bir şey yapıp yapmadığımdan emin değilim, fakat benim durumumda drop = FALSE seçeneği çalışmıyor. Böyle bir şey oldu beklenen Ne

library(splitstackshape) 
jnk <- data.table(a = '1,2,3,4,5', b = 5) 
jnk 
#   a b 
# 1: 1,2,3,4,5 5 

cSplit(jnk, 'a', ',', 'long', drop = FALSE) 
# a b 
# 1: 1 5 
# 2: 2 5 
# 3: 3 5 
# 4: 4 5 
# 5: 5 5 

:

cSplit(jnk, 'a', ',', 'long', drop = FALSE) 
# a b a.orig 
# 1: 1 5 1,2,3,4,5 
# 2: 2 5 1,2,3,4,5 
# 3: 3 5 1,2,3,4,5 
# 4: 4 5 1,2,3,4,5 
# 5: 5 5 1,2,3,4,5 

kullanıyorum sürüm 1.4.2

+0

... Bu yüzden jnk <- data.table ile çalışmaz (a = c ('1,2,3,4,5', '1,2,3', '2,3'), b = c (5,4 , 3)) – drmariod

cevap

10

"uzun" biçiminde sütun değiştiren İşte

bir örnektir := ile atanan "data.table" içinde list(unlist(...)) kullanarak yerinde. Bu nedenle, drop kullanıldıysa, sütunu ayırır ve sonra kaldırırsınız!

Ben dropwide biçimi için sadece olduğunu belgelerinde bu açık hale veya kullanıcı uzun formatta drop kullanmaya çalışırsa bir message eklemeye çalışacağım. file a FR or submit a PR'a çekinmeyin.

geçici çözüm (örneğin, "a_orig") ve daha sonra bölme yapmak başka bir sütun atamak olacaktır:

jnk <- data.table(a=c('1,2,3,4,5','1,2,3','2,3'),b=c(5,4,3)) 
cSplit(jnk[, a_orig := a], "a", ",", "long") 
#  a b a_orig 
# 1: 1 5 1,2,3,4,5 
# 2: 2 5 1,2,3,4,5 
# 3: 3 5 1,2,3,4,5 
# 4: 4 5 1,2,3,4,5 
# 5: 5 5 1,2,3,4,5 
# 6: 1 4  1,2,3 
# 7: 2 4  1,2,3 
# 8: 3 4  1,2,3 
# 9: 2 3  2,3 
# 10: 3 3  2,3 

Kapsamlı test etmedim ama olası bir düzeltme olabilir:

cSplit2 <- function(indt, splitCols, sep = ",", direction = "wide", 
        fixed = TRUE, drop = TRUE, stripWhite = TRUE, 
        makeEqual = NULL, type.convert = TRUE) { 
    if (direction == "long" & !drop) { 
    indt <- as.data.table(indt) 
    indt[, `:=`(eval(paste(splitCols, "orig", sep = "_")), 
       lapply(splitCols, function(x) indt[[x]]))] 
    } 
    cSplit(indt, splitCols, sep, direction, fixed, drop, stripWhite, 
     makeEqual, type.convert) 
} 

temel fikir sadece direction == "wide" ve drop = FALSE eğer girdi veri kümesini değiştirmektir. Bu, sahip olduğunuz düşünceye benzer, ancak muhtemelen, gerçek pakete, line 94 civarında bir yere entegre edilmiş bir çözüm olabilir. Bu durumda, sadece indt[, `:=`(eval(paste(splitCols, "orig", sep = "_")), lapply(splitCols, function(x) indt[[x]]))] kısmı gerekli olmalıdır.

0

Geri bildirim için teşekkürler, bir geçici çözüm olarak küçük bir işlev yazdım. data.table'u düzgün çalışmasını sağlamak için data.frame'u değiştirmek zorunda kaldım. data.table durumunda ek bir parametre ayarlamam gerekiyor ama data.frame ile çöküyor. Benim durumumda, data.frame'un çoğuna ihtiyacım var, bu yüzden onu optimize ettim.

Bu `jnk [[ 'a']]` aynı uzunlukta olması gerekir yoksa her seferinde eklenmiş olur çünkü df daha hatları, varsa işe kesin yapar
library(splitstackshape) 
jnk <- data.frame(a = c('1,2,3,4,5','1,2,3','2,3'), 
        b = c('a,b,c,d,e','a,b,c','a,b'), 
        c = c(5,4,3)) 
jnk 

myCSplit <- function(data_set, splitCols, sep = ',', direction = 'long', drop = TRUE, ...) { 
    if(direction == 'long' & !drop) { 
    orig_names <- sub('$', '_orig', splitCols) 
    df <- as.data.frame(data_set[,splitCols]) 
    names(df) <- orig_names 
    df2 <- cbind(data_set, df) 
    return(cSplit(df2, splitCols, sep, 'long')) 
    } else { 
    return(cSplit(data_set, splitCols, sep, direction, drop = drop,...)) 
    } 
} 
myCSplit(jnk, 'a', ',') 
myCSplit(jnk, 'a', ',', drop = FALSE) 
myCSplit(jnk, 'a', ',', 'wide') 
myCSplit(jnk, 'a', ',', 'wide', drop = FALSE) 
myCSplit(jnk, c('a','b'), ',', 'long', drop = FALSE) 
+2

Öğle yemeğinden daha genel bir çözümle geri dönmeme izin verin. – A5C1D2H2I1M1N2O1R2T1

+0

Hey @AnandaMahto belki bu özelliği bir sonraki sürüme ekleyebilirsin ... Benim durumumda çok yararlı olur. – drmariod

+2

Anlatabildiğim kadarıyla, tek bir çizgiyle düzeltmeyi yapmam mümkün olabilir. Görmek için bazı testler yapmak zorundayım. – A5C1D2H2I1M1N2O1R2T1