特定范围的垂直查找

时间:2017-02-01 14:35:15

标签: r

我有一个看起来像这样的数据框(这些是前24行):

row     Name         Age
1       John         22
2       Alice        29
3       Michael      33
4       Briefing     NA
5       Class        A
6       Year         2016
7       Observation  0
8       End          NA
9       Steward      35
10      Louis        20
11      Josh         22
12      Marie        39
13      Briefing     NA
14      Observation  2
15      Year         2017
16      End          NA
17      Adam         27
18      Joseph       26
19      Andrew       26
20      Briefing     NA
21      Observation  2
22      Year         2017
23      Class        B
24      End          NA

我希望它看起来像这样

  Name    Age  Class  Year  Observation
  John    22   A      2016  0
  Alice   29   A      2016  0
  Michael 33   A      2016  0
  Steward 35   NA     2017  2
  Louis   20   NA     2017  2
  Josh    22   NA     2017  2
  Marie   39   NA     2017  2
  Adam    27   B      2017  2
  Joseph  26   B      2017  2
  Andrew  26   B      2017  2

我知道这个过程需要我:

  • 检测必须传输数据的每个范围:来自单词" Briefing"单词"结束"。
  • 由于组件发生变化,我还需要将信息分类到各自的列中:第一组将信息传输到列" Class"," Year"和"观察"而第二组只到列#34;年"和"观察"离开专栏" Class"具有NA值。第三组再一次为列提供信息" Class"," Year"和"观察"。

我很感激你的帮助,用R来解决这个问题。

编辑:这是dput

    structure(list(row = 1:24, Name = structure(c(7L, 2L, 12L, 4L, 
5L, 15L, 13L, 6L, 14L, 10L, 9L, 11L, 4L, 13L, 15L, 6L, 1L, 8L, 
3L, 4L, 13L, 15L, 5L, 6L), .Label = c("Adam", "Alice", "Andrew", 
"Briefing", "Class", "End", "John", "Joseph", "Josh", "Louis", 
"Marie", "Michael", "Observation", "Steward", "Year"), class = "factor"), 
    Age = structure(c(6L, 9L, 10L, NA, 13L, 4L, 1L, NA, 11L, 
    3L, 6L, 12L, NA, 2L, 5L, NA, 8L, 7L, 7L, NA, 2L, 5L, 14L, 
    NA), .Label = c("0", "2", "20", "2016", "2017", "22", "26", 
    "27", "29", "33", "35", "39", "A", "B"), class = "factor")), .Names = c("row", 
"Name", "Age"), class = "data.frame", row.names = c(NA, -24L))

1 个答案:

答案 0 :(得分:1)

基本上,你有两个数据帧一起按行扫描。我们将它们分开然后按列连接在一起。

library(dplyr)
library(tidyr)

# flag rows as being part of the "lookup" data frame
# and add a grouping so we know which lookup values belong with which data values
df = mutate(df, group = cumsum(df$Name == "End"),
       is_lookup = cumsum(Name == "Briefing") > cumsum(Name == "End") | Name == "End") %>%
    select(-row)

# break off the lookup data and make it wide
lookup = filter(df, is_lookup,
                ! Name %in% c("Briefing", "End")) %>%
    spread(key = Name, value = Age)

# break off the non-lookup data and join it to the wide lookup
df %>% filter(!is_lookup) %>%
    select(Name, group) %>% 
    left_join(lookup) %>%
    select(-group, -is_lookup)
# Joining, by = "group"
#       Name Class Observation Year
# 1     John     A           0 2016
# 2    Alice     A           0 2016
# 3  Michael     A           0 2016
# 4  Steward  <NA>           2 2017
# 5    Louis  <NA>           2 2017
# 6     Josh  <NA>           2 2017
# 7    Marie  <NA>           2 2017
# 8     Adam     B           2 2017
# 9   Joseph     B           2 2017
# 10  Andrew     B           2 2017