【问题标题】:How to transform/resample/interpolate data for normalising variable length within a tidy dataset with multiple grouping variables in R?如何在R中具有多个分组变量的整洁数据集中转换/重新采样/插值数据以标准化可变长度?
【发布时间】:2018-05-23 13:56:26
【问题描述】:

我的目标是标准化向量的长度,以便在整洁的数据集中进行平均。使用 approx 似乎是要走的路,但我不能让它在 tidyverse 中有效地工作。一个问题可能与在数据框中调整大小有关。这是一个可重现的示例:

# create reproducible dataset
i = 80
I = 110
id = rep("AA", I+i)
event = rep("event1", I+i)
sub_event = NA
sub_event[1:i] = 1
sub_event[i+1:I] = 2
sub_event = as.factor(sub_event)
y1 = sin(seq(0, 5*pi, length.out = i))
y2 = sin(seq(0, 5*pi, length.out = I))
y3 = cos(seq(0, 5*pi, length.out = i))
y4 = cos(seq(0, 5*pi, length.out = I))
var1 = c(y1,y2)
var2 = c(y3,y4)

df1 <- data.frame(id, event, sub_event,var1, var2)
df2 <- df1
df2$event = "event2"
df <- rbind(df1, df2)
temp <- df
temp$id = "BB"
df <- rbind(df, temp)


# create a "time" vector for sub_event

df <- df %>% 
  group_by(id, event, sub_event) %>%
  mutate(sub_event_time = seq_along(var1)) %>%
  select(id, event, sub_event, sub_event_time, everything()) %>%
  ungroup()

绘制 var1

# plot 
ggplot(df,
       aes(x=sub_event_time, y=var1, colour = sub_event)) + 
  geom_point() +
  geom_path() +
  facet_wrap(id~event)

我希望转换/重新采样数据以获取每个 sub_events 的 var1 长度,使其成为每个 id 的每个事件中最长的 sub_event 的长度。

例如我们想要:事件 1 子事件 1 的 var1 长度 = 事件 1 子事件 2 的 var1 长度(最长)。

这是一个尝试:

# attempt for var1 only
aim.df <- df %>%
  ungroup() %>%
  select(-var2) %>%
  group_by(id, event) %>%
  mutate(max_sub_event_time = max(sub_event_time)) %>%
  mutate(var1 = approx(var1, n = max_sub_event_time)$y) 

这会返回以下错误:

    Error in mutate_impl(.data, dots) : 
    Column `var1` must be length 190 (the group size) or one, not 110
    In addition: Warning messages:
    1: In if (n <= 0) stop("'approx' requires n >= 1") :
    the condition has length > 1 and only the first element will be used
    2: In seq.int(x[1L], x[nx], length.out = n) :
    first element used of 'length.out' argument

有什么想法吗?

【问题讨论】:

  • “var1 的长度”是什么意思?组内var1 的观察次数?
  • 如果是这样,你希望var1 的值是什么?
  • @CJYetman :是的 var1 的长度表示 var1 中的观察次数(针对特定事件)。最终目标是重新采样信号 (var1 var2) 以在每个事件的 sub_events 中具有相同数量的观察值;这样就可以实现对每个事件的子事件变量进行逐点平均。

标签: r dplyr tidyr


【解决方案1】:

步骤...

  1. group_by(id, event, sub_event)
  2. 删除sub_event_time,因为一旦添加观察,它将不再相关
  3. summarise approx 函数的结果作为列表列(您必须将 var1max_sub_event_time 转换为 approx 的适当输入)
  4. unnest结果列表列
  5. 再次group_by(id, event, sub_event) 并添加一个新的sub_event_time

代码...

library(dplyr)
library(tidyr)

df %>%
  ungroup() %>%
  select(-var2) %>%
  group_by(id, event) %>%
  mutate(max_sub_event_time = max(sub_event_time)) %>% 
  group_by(id, event, sub_event) %>% 
  select(-sub_event_time) %>% 
  summarise(var1_int = list(approx(as.numeric(var1), n = first(max_sub_event_time))$y)) %>% 
  unnest() %>% 
  group_by(id, event, sub_event) %>% 
  mutate(sub_event_time = row_number())

【讨论】:

  • 太棒了!如果我们希望使用 summarise_at 为 var1 和 var2 提供它,是否可行?
  • 当然,我不明白为什么不
猜你喜欢
  • 1970-01-01
  • 2019-07-17
  • 2020-11-28
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-17
相关资源
最近更新 更多