使用数据表对子集执行操作

And*_*eas 6 r plyr data.table data-cleaning

我有一个广泛的调查数据集.对于特定问题,在原始数据中创建了一组变量,以表示在特定月份询问调查问题的事实.

我希望创建一组具有月不变名称的新变量; 这些变量的值将对应于观察到的月份的月变量问题的值.

请参阅示例/虚构数据集:

require(data.table)

data <- data.table(month = rep(c('may', 'jun', 'jul'),  each = 5),
                   may.q1 = rep(c('yes', 'no', 'yes'),  each = 5),
                   jun.q1 = rep(c('breakfast', 'lunch', 'dinner'),  each = 5),
                   jul.q1 = rep(c('oranges', 'apples', 'oranges'),  each = 5),
                   may.q2 = rep(c('econ', 'math', 'science'), each = 5),
                   jun.q2 = rep(c('sunny', 'foggy', 'cloudy'), each = 5),
                   jul.q2 = rep(c('no rain', 'light mist', 'heavy rain'), each = 5))
Run Code Online (Sandbox Code Playgroud)

在这项调查中,实际上只有两个问题:"q1"和"q2".这些问题中的每一个都被反复询问了几个月.但是,仅当数据中观察到的月份与特定月份的调查问题匹配时,观察才包含有效响应.

例如:对于"May"中的任何观察,"may.q1"被观察为"是".我想要一个新的"Q1"变量来表示"may.q1","jun.q1"和"jul.q1".当月份为"可能"时,"Q1"的值将取"may.q1"的值,而当月份为"jun"时,"Q1"的值将取值"jun.q1"的值.

如果我尝试使用数据表手动执行此操作,我想要的是:

mdata <- data[month == 'may', c('month', 'may.q1', 'may.q2'), with = F]
setnames(mdata, names(mdata), gsub('may\\.', '', names(mdata)))
Run Code Online (Sandbox Code Playgroud)

我想要重复"by = month".

如果我使用"plyr"包作为数据框,我会使用以下方法解决:

require(plyr)
data <- data.frame(data)

mdata <- ddply(data, .(month), function(dfmo) {
    dfmo <- dfmo[, c(1, grep(dfmo$month[1], names(dfmo)))]
    names(dfmo) <- gsub(paste0(dfmo$month[1], '\\.'), '', names(dfmo))
    return(dfmo)
})
Run Code Online (Sandbox Code Playgroud)

任何使用data.table方法的帮助都会非常感激,因为我的数据很大.谢谢.

Mat*_*wle 6

一种不同的说明方式:

data[, .SD[,paste0(month,c(".q1",".q2")), with=FALSE], by=month]

    month  may.q1     may.q2
 1:   may     yes       econ
 2:   may     yes       econ
 3:   may     yes       econ
 4:   may     yes       econ
 5:   may     yes       econ
 6:   jun   lunch      foggy
 7:   jun   lunch      foggy
 8:   jun   lunch      foggy
 9:   jun   lunch      foggy
10:   jun   lunch      foggy
11:   jul oranges heavy rain
12:   jul oranges heavy rain
13:   jul oranges heavy rain
14:   jul oranges heavy rain
15:   jul oranges heavy rain
Run Code Online (Sandbox Code Playgroud)

但请注意,列名称来自第一组(之后可以使用重命名setnames).如果有大量的列只需要少量,那么它可能不是最有效的.在这种情况下,Arun的解决方案融化为长格式应该更快.