【问题标题】:paste together first and last value of grouping variable将分组变量的第一个值和最后一个值粘贴在一起
【发布时间】:2019-07-15 11:52:07
【问题描述】:

我有一个看起来像这样的 df:

group sequence link 
90      1      11|S1
90      2      10|S1
90      3      12|10
91      1      9|10
91      2      13|9
93      1      15|20
...

如何将每个组中linkvariable 的第一个和最后一个值存储为新变量? 期望的输出是:

group sequence link  Key
90      1      11|S1 11|S1, 12|10
90      2      10|S1 11|S1, 12|10
90      3      12|10 11|S1, 12|10
91      1      9|10  9|10, 13|9
91      2      13|9 9|10,13|9
93      1      15|20 
....

【问题讨论】:

  • 您的示例中是否有错字,第 92 组仍应为第 91 组?
  • 哦,是的。编辑它。谢谢!

标签: r dataframe data.table tidyverse


【解决方案1】:

你可以这样做:

library(dplyr)

df %>%
  group_by(group) %>%
  mutate(
    Key = paste(link[1], link[n()], sep = ", ")
  )

虽然这与您想要的输出不匹配。在您的示例数据框中,您有例如组 91 只有 1 个值。上面的代码会重复给你9|10 作为开始和结束。

如果您希望在这种情况下只显示一个值,您可以这样做:

df %>%
  group_by(group) %>%
  mutate(
    Key = case_when(
      n() > 1 ~ paste(link[1], link[n()], sep = ", "), 
      TRUE ~ as.character(link)
      )
  )

【讨论】:

  • 太棒了!谢谢你!对于其他读者:确保使用dplyr::mutate
【解决方案2】:

我认为您可以使用arrange()slice() 来查找数据中的第一个/最后一个链接。我的解决方案比 @arg0naut91 的解决方案更长,但可能更直观。

创建玩具数据框...

df <- data.frame(group=rep(letters,3), # create toy data frame
                 sequence=rep(1:3,26),
                 link=sample(9:13,78,T)) %>% 
  arrange(group,sequence) %>% # arrange data
  group_by(group,link) %>% sample_n(1) %>% # remove any duplicate link values (to create uneven sequence var)
  ungroup() %>% arrange(group,sequence) # arrange again to view
glimpse(df)

查找第一个和最后一个链接。将它们作为新列添加到数据框中。

df <- df %>% arrange(group,link) %>% group_by(group) %>% 
  slice(1) %>% mutate(link.first=link) %>% # find first link for each group
  select(group,link.first) %>% left_join(df,.) # add to original data frame
df <- df %>% arrange(group,link) %>% group_by(group) %>% 
  slice(n()) %>% mutate(link.last=link) %>% # find last link for each group
  select(group,link.last) %>% left_join(df,.) # add to original data frame

df %>% mutate(key=paste(link.first,link.last,sep=', ')) # paste links to form key

# A tibble: 62 x 6
   group sequence  link link.first link.last key   
   <fct>    <int> <int>      <int>     <int> <chr> 
 1 a            1    10         10        12 10, 12
 2 a            2    12         10        12 10, 12
 3 b            2     9          9        11 9, 11 
 4 b            3    11          9        11 9, 11 
 5 c            1    13          9        13 9, 13 
 6 c            2    12          9        13 9, 13 
 7 c            3     9          9        13 9, 13 
 8 d            1     9          9        13 9, 13 
 9 d            3    13          9        13 9, 13 
10 e            1    11          9        11 9, 11 

由于我使用sample() 替换生成数据,可能有一些group 只有一行(即相同的第一个和最后一个链接值),可以过滤掉。

df %>% filter(link.first==link.last)

# A tibble: 2 x 5
  group sequence  link link.first link.last
  <fct>    <int> <int>      <int>     <int>
1 k            2     9          9         9
2 z            1     9          9         9

df %>% count(group) %>% filter(n==1)

【讨论】:

  • 感谢您的回复!不幸的是,这对我也不起作用。它适用于行数较少 (last.link
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
  • 1970-01-01
相关资源
最近更新 更多