重构和格式化数据框列

时间:2017-08-03 00:39:07

标签: r data.table dplyr multidplyr

dfin <- 

ID   SEQ   GRP   C1   C2   C3   T1   T2   T3
1     1     1    0     5    8   0     1   2
1     2     1    5     10   15  5     6   7
2     1     2    20    25   30  0     1   2

C1是T1(CONC)处的浓度(TIME),依此类推。这就是我想要的输出:

dfout <- 

ID   SEQ   GRP  CONC  TIME
1     1     1    0     0
1     1     1    5     1
1     1     1    8     2
1     2     1    5     5
1     2     1    10    6
1     2     1    15    7
2     1     2    20    0
2     1     2    25    1
2     1     2    30    2

dfin有更多列CxTx,其中x是浓度读数的数量。

1 个答案:

答案 0 :(得分:3)

您可以使用data.table::melt执行此操作,并可根据列模式将表格熔化为多个列:

library(data.table)
melt(
    setDT(df), 
    id.vars=c("ID", "SEQ", "GRP"), 
    # columns starts with C and T should be melted into two separate columns
    measure.vars=patterns("^C", "^T"),     
    value.name=c('CONC', 'TIME')
)[order(ID, SEQ)][, variable := NULL][]

#   ID SEQ GRP CONC TIME
#1:  1   1   1    0    0
#2:  1   1   1    5    1
#3:  1   1   1    8    2
#4:  1   2   1    5    5
#5:  1   2   1   10    6
#6:  1   2   1   15    7
#7:  2   1   2   20    0
#8:  2   1   2   25    1
#9:  2   1   2   30    2

或者,如果值列名遵循模式[CT][0-9],则可以通过指定reshape来使用基数R中的sep=""split = if (sep == "") { list(regexp = "[A-Za-z][0-9]", include = TRUE) } else { list(regexp = sep, include = FALSE, fixed = TRUE)} 将通过字母/数字分隔将值列名分开由于此默认设置(来自?重塑):

reshape(df, varying=-(1:3), idvar=c("ID", "SEQ", "GRP"), 
        dir="long", sep="", v.names=c("CONC", "TIME"))

#   ID SEQ GRP time CONC TIME
#1:  1   1   1    1    0    5
#2:  1   2   1    1    5   10
#3:  2   1   2    1   20   25
#4:  1   1   1    2    8    0
#5:  1   2   1    2   15    5
#6:  2   1   2    2   30    0
#7:  1   1   1    3    1    2
#8:  1   2   1    3    6    7
#9:  2   1   2    3    1    2
class MyViewController: UIViewController {
    private var observer: NSKeyValueObservation?

    func configureKVO() {
        observer = MySingleton.shared.observe(\.shouldFetchDataFromServer) { (manager, change) in
            print("Changed: \(manager.shouldFetchDataFromServer)")
        }
        MySingleton.shared.shouldFetchDataFromServer = false
        MySingleton.shared.shouldFetchDataFromServer = true
    }
}

class MySingleton: NSObject {
    static let shared = MySingleton()
    @objc var shouldFetchDataFromServer: Bool = false
}