【问题标题】:Merging two data frames in long format based on date根据日期合并两个长格式数据帧
【发布时间】:2020-07-23 02:34:21
【问题描述】:

我有 2 个数据框,一个 (df1) 记录每天发生的不同活动,另一个 (df2) 记录一天中发生的活动的属性。

从df1 可以识别活动的重复发生以及持续时间。一天的开始时间由Date 变量指定。

例如:

  • id 12 事件从第 1 天开始,到第 7 天结束。在本例中,出现次数为 7,持续时间为 11。
  • 对于id 123,一周从第 5 天开始,到第 7 天结束;重复顺序发生,因为第 6 天有间隔天,持续时间为 6,id 123(从第 6 天开始,到第 7 天结束)连续发生 2 次,持续时间为 6。

在df1 中,变量 Date 定义记录开始的日期。例如 id 12 记录从第 1 天开始,依此类推。

我想确定在连续发生期间是否有df2 中的活动属性记录。

例如 id 12,发生 7 次,持续时间为 12 有周三的记录(df1 中的第 3 天),此记录对应于连续发生的第 3 天。对于 id 123,没有数据(例如,没有连续出现),但对于 id 10,出现 6 天,持续时间 18 有第 6 天的记录。

Df1:

id   day1 day2 day3 day4 day5 day6  day7   Date
 12    2    1    2    1    1    3    1     Mon
123    0    3    0    3    3    0    3     Fri
 10    0    3    3    3    3    3    3     Sat

Df2:

    id   c1 c2  Date
    12   3   3   Wednesday
   123   3   2   Fri
     10  3   1   Sat

结果:

 id c1 c2  Occurrence Position
 12 3   3     7          3
123 0   0     0          0
 10 3   1     2          1

样本数据:df1

structure(list(id = c(12L, 123L, 10L), day1 = c(2L, 0L, 3L), 
    day2 = c(1L, 3L, 3L), day3 = c(2L, 0L, 3L), day4 = c(1L, 
    3L, 3L), day5 = c(1L, 3L, 3L), day6 = c(3L, 0L, 3L), day7 = c(1L, 
    3L, 3L), Date = c("Monday", "Friday", "Saturday")), row.names = c(NA, 
-3L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x000002a81a571ef0>)

df2:

structure(list(id = c(12, 123, 10), c1 = c(3, 3, 3), c2 = c(3, 
2, 1), Date = structure(c(3L, 1L, 2L), .Label = c("Friday", "Saturday", 
"Wednesday"), class = "factor")), row.names = c(NA, -3L), class = "data.frame")

【问题讨论】:

  • df2中c1和c2是什么意思
  • 为什么 c1 和 c2 的结果为 0?
  • @ava 描述了以连续顺序发生的活动的不同特征。基本上它表明当时有观察结果。
  • @ava 例如,在 id 12 的情况下,有一条关于正在发生的活动的记录在星期三。此外,在一周内活动发生 7 次的情况下,此记录是在 3 天内完成的。
  • @ c1 和 c2 在结果中,因为在 am 中是否有关于连续出现的建议以及是否进行了任何记录以及何时进行。

标签: r dataframe matrix


【解决方案1】:

dplyr 的解决方案(可能不是最短的):

# library
library(tidyverse)

# get data
df1 <- structure(list(id = c(12L, 123L, 10L), 
               day1 = c(2L, 0L, 3L), 
               day2 = c(1L, 3L, 3L), 
               day3 = c(2L, 0L, 3L), 
               day4 = c(1L,3L, 3L), 
               day5 = c(1L, 3L, 3L), 
               day6 = c(3L, 0L, 3L), 
               day7 = c(1L,3L, 3L), 
               Date = c("Monday", "Friday", "Saturday")),
               row.names = c(NA,-3L), class = c("data.table", "data.frame"))


df2 <- structure(list(id = c(12, 123, 10),
                      c1 = c(3, 3, 3), 
                      c2 = c(3, 2, 1),
                      Date = structure(c(3L, 1L, 2L), .Label = c("Friday", "Saturday","Wednesday"),
                                       class = "factor")), row.names = c(NA, -3L), class = "data.frame")


# change days to nummeric (will help you later)
df1 %>% mutate(
  Date_nr_df1=case_when(
    Date=="Monday" ~ 1,
    Date=="Tuesday" ~2,
    Date=="Wednesday" ~3,
    Date=="Thursday" ~4,
    Date=="Friday" ~5,
    Date=="Saturday" ~6,
    Date=="Sunday" ~7)) -> df1

df2 %>% mutate(
  Date_nr_df2=case_when(
    Date=="Monday" ~ 1,
    Date=="Tuesday" ~2,
    Date=="Wednesday" ~3,
    Date=="Thursday" ~4,
    Date=="Friday" ~5,
    Date=="Saturday" ~6,
    Date=="Sunday" ~7)) -> df2

# combine data by the id column
left_join(df1,df2, by=c("id")) -> df     

# adjust data   
df %>%
  group_by(id) %>% # to make changes per row
  mutate(days=paste0(day1,day2,day3,day4,day5,day6,day7)) %>% #pastes the values together
  mutate(days_correct=substring(days,Date_nr_df1)) %>% # applies the start day
  mutate(Occurrence_seq=str_split(days_correct, fixed("0"))[[1]][1]) %>% # extracts all days before 0
  mutate(Occurrence=nchar(Occurrence_seq)) %>%  ## counts these days
  mutate(Occurrence=case_when(Occurrence==1 ~ 0, TRUE ~ as.numeric(Occurrence))) %>% # sets Occurrence to 0 if there is no consecutive occurrence
  mutate(Position=Date_nr_df2-Date_nr_df1+1) %>% ## calculates the position you wanted
  mutate(c1=case_when(Occurrence==0 ~0, TRUE ~ c1),
         c2=case_when(Occurrence==0 ~0, TRUE ~c1),
         Position=case_when(Occurrence==0 ~ 0, TRUE ~ as.numeric(Position))) %>% 
  ungroup() %>% ungroups the df
  select(id,c1,c2,Occurrence,Position) # selects the wanted variables
#> # A tibble: 3 x 5
#>      id    c1    c2 Occurrence Position
#>   <dbl> <dbl> <dbl>      <dbl>    <dbl>
#> 1    12     3     3          7        3
#> 2   123     0     0          0        0
#> 3    10     3     3          2        1

由reprex package (v0.2.1) 于 2020-04-10 创建

【讨论】:

  • 非常感谢您有空的时候能不能解释一下代码
  • 非常感谢代码和解释 - 如果你有时间可以看看这个问题。区别在于时间步长 (95 x 7) stackoverflow.com/questions/61187493/…
猜你喜欢
  • 2021-10-05
  • 2021-08-06
  • 2016-12-10
  • 2020-07-24
  • 2021-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-02
相关资源
最近更新 更多