【问题标题】:Select the second observation per group in R在 R 中选择每组的第二个观察值
【发布时间】:2026-02-05 14:50:01
【问题描述】:

我觉得这应该是直截了当的,但我想不通。我想从数据框中按组选择第二个观察值。

例如:

Row Number    Email 
           1             xxxx
           2             xxxx
           3             xxxx
           4             xxxx
           5             xxxx
           6             yyyy
           7             yyyy
           8             zzzz
           9             zzzz
           10            zzzz
           11            zzzz
           12            zzzz

我想要:

Row Number    Email 
           2             xxxx
           7             yyyy
           9             zzzz

似乎 data.table 解决方案和聚合解决方案正在跳过他们应该捕获的电子邮件组。以下是它应该捕获的前六秒行:

Row Number   emails   expected output   actual output
1            aaaa
2            aaaa     aaaa              aaaa
3            aaaa
4            aaaa
5            aaaa
6            aaaa
7            aaaa
8            bbbb
9            bbbb     bbbb              bbbb
10           cccc
11           cccc     cccc              cccc
12           cccc
13           cccc
14           cccc
15           cccc
16           cccc
17           dddd     NA
18           eeee
19           eeee     eeee
20           eeee
21           ffff
22           ffff     ffff              ffff

email 'eeee' 在数据集中有一行,所以我希望这一行有一个 NA 行。 email 'dddd' 在原始数据集中有三行,所以我希望这封电子邮件的第二行,但它不存在。

【问题讨论】:

  • 每组电子邮件。对于所有等于“xxxx”的电子邮件,选择第二个观察值。对不起,也许我误用了这个词。它们在我的完整数据集中按时间排序

标签: r


【解决方案1】:

试试这个。无需包:

subset(DF, ave(RowNumber, Email, FUN = seq_along) == 2)

DF[ ave(DF$RowNumber, DF$Email, FUN = seq_along) == 2, ]

使用下面注释下显示的数据会产生三行:

  RowNumber Email
2         2  xxxx
7         7  yyyy
9         9  zzzz

样本数据没有单行组,问题没有指定如何处理这些组,但这些答案没有为这些组生成任何行。我想你会发现有些答案给出了相同的结果,而另一些则给出了将RowNumber 字段设置为NA 的一行。

注意:

我们将它用于输入数据DF

Lines <- "RowNumber    Email 
           1             xxxx
           2             xxxx
           3             xxxx
           4             xxxx
           5             xxxx
           6             yyyy
           7             yyyy
           8             zzzz
           9             zzzz
           10            zzzz
           11            zzzz
           12            zzzz"
DF <- read.table(text = Lines, header = TRUE)

下次请提供代码以在问题中创建输入数据。

【讨论】:

  • 我不知道为什么,但你的解决方案只返回一个观察结果。
  • 没有。使用显示的输入数据,它们会产生所示的三行。
【解决方案2】:

或使用data.table

library(data.table)
setDT(df)[, .SD[2L], by = Email]
#    Email Row.Number
# 1:  xxxx          2
# 2:  yyyy          7
# 3:  zzzz          9

或以 R 为基数

aggregate(. ~ Email, df, function(x) x[2L])
#   Email Row.Number
# 1  xxxx          2
# 2  yyyy          7
# 3  zzzz          9

编辑:使用新数据集

df <- read.table(text = "'Row Number'   emails
                1            aaaa
                 2            aaaa             
                 3            aaaa
                 4            aaaa
                 5            aaaa
                 6            aaaa
                 7            aaaa
                 8            bbbb
                 9            bbbb  
                 10           cccc
                 11           cccc   
                 12           cccc
                 13           cccc
                 14           cccc
                 15           cccc
                 16           cccc
                 17           dddd
                 18           eeee
                 19           eeee     
                 20           eeee
                 21           ffff
                 22           ffff", header = TRUE)

运行代码

setDT(df)[, .SD[2L], by = emails]
#    emails Row.Number
# 1:   aaaa          2
# 2:   bbbb          9
# 3:   cccc         11
# 4:   dddd         NA
# 5:   eeee         19
# 6:   ffff         22

【讨论】:

  • 我能否将“2L”更改为“3L”,这样会选择每个电子邮件组的第三个观察值?它似乎不像那样工作。
  • 是的。您可以将2L 更改为3L,它将选择每个组中的第三个观察值。唯一的问题是您在 yyyy 组中没有 3 个观察值,因此它将为该特定组返回 NA
  • 没关系。谢谢!对于我的完整数据集,它似乎适用于某些电子邮件地址,但并非全部。对于某些人来说,它需要第二次观察,但不是对于每个唯一的电子邮件地址。知道为什么会这样做吗?
  • 不确定你的意思。当这不起作用时,你能举个例子吗?
  • 我已经编辑了我的原始帖子。请让我知道这是否有意义。
【解决方案3】:

你可以使用包dplyr来试试这个

d <- read.table(header = TRUE, text = "
Number    Email 
           1             xxxx
           2             xxxx
           3             xxxx
           4             xxxx
           5             xxxx
           6             yyyy
           7             yyyy
           8             zzzz
           9             zzzz
           10            zzzz
           11            zzzz
           12            zzzz")

library(dplyr)
group_by(d, Email) %>%
    slice(2)
#    Source: local data frame [3 x 2]
#    Groups: Email
#      Number Email
#    1      2  xxxx
#    2      7  yyyy
#    3      9  zzzz

【讨论】:

  • 或明确d 不是分组变量:d %&gt;% group_by(Email) %&gt;% slice(2)
最近更新 更多