R DataTable加入和约束行

时间:2013-09-18 11:56:12

标签: r data.table reshape

我想在数据表中总结一组观察结果,并可以使用语法方面的一些帮助。

我认为这就像连接一样简单,但是我试图确定在特定的观察DAY上看到的特定值,即使它在当天的多个测量或传感器上也是如此。

  • 观察按日期汇总
  • 观察日期有不同的测量计数(每个日期的行数)
  • ' M'测量列表明当天在任何传感器中都观察到了特定值。

我已经创建了两组样本数据,希望能够澄清目标。我还创建了一个excel电子表格图片,希望能够显示数据之间的关系。

library(data.table)
raw <- data.table(
  Date = as.Date(c("2013-5-4","2013-5-4","2013-5-4", "2013-5-9","2013-5-9", "2013-5-16","2013-5-16","2013-5-16", "2013-5-30")),
  S1 = c(4, 2, 3, 1, 1, 8, 7, 3, 3),
  S2 = c(2, 5, 2, 4, 4, 9, 1, 6, 4),
  S3 = c(6, 2, 2, 7, 3, 2, 7, 2, 1)
)

summarized <- data.table(
  Date = as.Date(c("2013-5-4", "2013-5-9", "2013-5-16", "2013-5-30")),
  M1 = c(FALSE,TRUE,TRUE,TRUE),
  M2 = c(TRUE,FALSE,TRUE,FALSE),
  M3 = c(TRUE,TRUE,TRUE,TRUE),
  M4 = c(TRUE,FALSE,FALSE,TRUE),
  M5 = c(TRUE,FALSE,FALSE,FALSE),
  M6 = c(TRUE,FALSE,TRUE,FALSE),
  M7 = c(FALSE,TRUE,TRUE,FALSE),
  M8 = c(FALSE,FALSE,TRUE,FALSE),
  M9 = c(FALSE,FALSE,TRUE,FALSE),
  M10 = c(FALSE,FALSE,TRUE,FALSE)
)

Excel image showing the relationship between the sets of data Excel中

Raw是测量输入。多次测量可以在同一观察日期(即多行)进行。

总结是我希望得到的结果。总结行,并且“简化”列仅表示在任何V列中的当天观察到值(在M之后,即M1,M2)。例如,在5/16的第一个和最后一个观察中看到数字2,但在5/16的9个值中没有看到数字5。

我想我需要使用连接但是如何计算M列逃脱了我。

非常感谢任何帮助。

问题:数据科学或数学中是否存在此类操作的名称?

更新: 我正在尝试以下

setkey(raw,Date)
s <- data.table( Date=unique(raw$Date)) # get a datatable of the unique dates
setkey(s,Date)
s[raw, M1:=(length(na.omit(match(c(raw$V1,raw$v2,raw$v3),1)))>=1)]

请注意,这些值不是5-4的预期值(应为FALSE)。我认为这是因为我的匹配语句中的原始行没有受到限制。

         Date   M1
1: 2013-05-04 TRUE
2: 2013-05-09 TRUE
3: 2013-05-16 TRUE
4: 2013-05-30 TRUE

我的猜测是我需要使用不同的东西来对连接中的原始行进行子集化。

2 个答案:

答案 0 :(得分:3)

这似乎有效:

raw[,lapply(1:10,`%in%`,unique(unlist(.SD))),by=Date]

结果是

         Date    V1    V2   V3    V4    V5    V6    V7    V8    V9   V10
1: 2013-05-04 FALSE  TRUE TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE
2: 2013-05-09  TRUE FALSE TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE FALSE
3: 2013-05-16  TRUE  TRUE TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE FALSE
4: 2013-05-30  TRUE FALSE TRUE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE

如果您希望列“M”而不是“V”,请使用c(M=1:10)代替1:10

答案 1 :(得分:1)

这是一个重塑问题。

首先,由于数据来自哪个传感器无关紧要,让我们将您的三列合并为一列。

temp <- raw[,Reduce(union,list(S1,S2,S3)),by=Date]

现在我们想要从“长”格式转变为“宽”格式。

this answer借来的数据表解决方案:

setkey(temp,Date,V1)
temp[CJ(unique(Date),unique(V1)), list(.N)][,
  setNames(as.list(as.logical(N)), paste0("M",unique(V1))), by = Date]
         # Date    M1    M2   M3    M4    M5    M6    M7    M8    M9
# 1: 2013-05-04 FALSE  TRUE TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
# 2: 2013-05-09  TRUE FALSE TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE
# 3: 2013-05-16  TRUE  TRUE TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE
# 4: 2013-05-30  TRUE FALSE TRUE  TRUE FALSE FALSE FALSE FALSE FALSE

Base reshape以这种方式工作:

as.data.table(reshape(temp, timevar = "V1", v.names = "V1", idvar = "Date", direction = "wide"))
         # Date V1.4 V1.2 V1.3 V1.5 V1.6 V1.1 V1.7 V1.8 V1.9
# 1: 2013-05-04    4    2    3    5    6   NA   NA   NA   NA
# 2: 2013-05-09    4   NA    3   NA   NA    1    7   NA   NA
# 3: 2013-05-16   NA    2    3   NA    6    1    7    8    9
# 4: 2013-05-30    4   NA    3   NA   NA    1   NA   NA   NA

## to order by column
temp2 <- as.data.table(reshape(temp[order(V1)], timevar = "V1", v.names = "V1", idvar = "Date", direction = "wide"))
         # Date V1.1 V1.2 V1.3 V1.4 V1.5 V1.6 V1.7 V1.8 V1.9
# 1: 2013-05-09    1   NA    3    4   NA   NA    7   NA   NA
# 2: 2013-05-16    1    2    3   NA   NA    6    7    8    9
# 3: 2013-05-30    1   NA    3    4   NA   NA   NA   NA   NA
# 4: 2013-05-04   NA    2    3    4    5    6   NA   NA   NA

##converts to logical true/false
temp2[,lapply(.SD,function(x) {x[is.na(x)] <- 0; as.logical(x)}), by = Date]
       # Date   vv  V1.1  V1.2 V1.3  V1.4  V1.5  V1.6  V1.7  V1.8  V1.9
# 1: 2013-05-09 TRUE  TRUE FALSE TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE
# 2: 2013-05-16 TRUE  TRUE  TRUE TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE
# 3: 2013-05-30 TRUE  TRUE FALSE TRUE  TRUE FALSE FALSE FALSE FALSE FALSE
# 4: 2013-05-04 TRUE FALSE  TRUE TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE

reshape2更直观一些:

require(reshape2)
## dummy variable for TRUE/FALSE
temp[,vv := TRUE]
temp_reshape2 <- as.data.table(dcast(temp, Date ~ V1, value.var = "vv"))
## replace NA with FALSE
temp_reshape2[, lapply(.SD, function(x) {x[is.na(x)] <- FALSE; x}), by = Date]
         # Date     1     2    3     4     5     6     7     8     9
# 1: 2013-05-04 FALSE  TRUE TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
# 2: 2013-05-09  TRUE FALSE TRUE  TRUE FALSE FALSE  TRUE FALSE FALSE
# 3: 2013-05-16  TRUE  TRUE TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE
# 4: 2013-05-30  TRUE FALSE TRUE  TRUE FALSE FALSE FALSE FALSE FALSE

完成后,一个蹩脚的解析 - 解决方案:

limits <- temp[,c(min(V1),max(V1))]
sapply(temp[,min(V1) : max(V1)], function(x) {
temp[,eval(parse(text=paste0("M",x," := any(abs(V1 - ",x,") < .Machine$double.eps)"))),by = Date]
})