【问题标题】:R - Subset dataframe to include only subjects with more than 1 recordR - 子集数据框仅包含超过 1 条记录的主题
【发布时间】:2015-01-01 02:01:59
【问题描述】:

我想对数据框进行子集化,以包含具有 >1 条记录的主题的所有记录,并排除只有 1 条记录的主题。

让我们采用以下数据框;

mydata <- data.frame(subject_id = factor(c(1,2,3,4,4,5,5,6,6,7,8,9,9,9,10)),
                     variable = rnorm(15))

下面的代码使用 duplicated() 为我提供了 >1 条记录的主题;

duplicates <- mydata[duplicated(mydata$subject_id),]$subject_id

但我想在我的子集中为每个具有>1条记录的主题保留所有记录,所以我尝试了;

mydata[mydata$subject_id==as.factor(duplicates),]

这不会返回我期望的结果。

有什么想法吗?

【问题讨论】:

  • 您不需要(也不应该)使用as.data.frame(cbind(... )) 之类的东西。只需使用data.frame(var1 = ..., var2 = ...)(请参阅我对您问题的编辑)。这样,您还可以避免在全局环境中创建许多对象,例如 subject_id 和变量,尽管您只希望它们在 data.frame 中。

标签: r dataframe duplicates subset


【解决方案1】:

data.table 解决方案

set.seed(20)
subject_id <- as.factor(c(1,2,3,4,4,5,5,6,6,7,8,9,9,9,10))
variable <- rnorm(15)
mydata<-as.data.frame(cbind(subject_id, variable))

library(data.table)
setDT(mydata)[, .SD[.N > 1], by = subject_id] # @Thanks David.
#    subject_id   variable
# 1:          4 -1.3325937
# 2:          4 -0.4465668
# 3:          5  0.5696061
# 4:          5 -2.8897176
# 5:          6 -0.8690183
# 6:          6 -0.4617027
# 7:          9 -0.1503822
# 8:          9 -0.6281268
# 9:          9  1.3232209

【讨论】:

  • 我觉得应该是setDT(mydata)[, .SD[.N &gt; 1], by = subject_id],因为如果有不止一列,你需要用你的方法手动指定它们
  • @DavidArenburg,确实。
【解决方案2】:

一个简单的替代方法是使用dplyr

library(dplyr)
dfr <- data.frame(a=sample(1:2,10,rep=T), b=sample(1:5,10, rep=T))
dfr <- group_by(dfr, b)
dfr
# Source: local data frame [10 x 2]
# Groups: b
# 
#    a b
# 1  2 4
# 2  2 2
# 3  2 5
# 4  2 1
# 5  1 2
# 6  1 3
# 7  2 1
# 8  2 4
# 9  1 4
# 10 2 4
filter(dfr, n() > 1)
# Source: local data frame [8 x 2]
# Groups: b
# 
#   a b
# 1 2 4
# 2 2 2
# 3 2 1
# 4 1 2
# 5 2 1
# 6 2 4
# 7 1 4
# 8 2 4

【讨论】:

  • 谢谢。所有答案都有效,但我觉得这个和 data.table 解决方案最适用于其他问题。我选择了这个 b/c,它允许我继续使用 data.frame 而不是 data.table 的数据。
【解决方案3】:
Here you go (I changed your variable to var <- rnorm(15):


set.seed(11)

subject_id<-as.factor(c(1,2,3,4,4,5,5,6,6,7,8,9,9,9,10))
var<-rnorm(15)
mydata<-as.data.frame(cbind(subject_id,var))

x1 <- c(names(table(mydata$subject_id)[table(mydata$subject_id) > 1]))
x2 <- which(mydata$subject_id %in% x1)
mydata[x2,]

     subject_id   var
4           4  0.3951076
5           4 -2.4129058
6           5 -1.3309979
7           5 -1.7354382
8           6  0.4020871
9           6  0.4628287
12          9 -2.1744466
13          9  0.4857337
14          9  1.0245632

【讨论】:

    【解决方案4】:

    试试:

    > mydata[mydata$subject_id %in% mydata[duplicated(mydata$subject_id),]$subject_id,]
       subject_id   variable
    4           4 -1.3325937
    5           4 -0.4465668
    6           5  0.5696061
    7           5 -2.8897176
    8           6 -0.8690183
    9           6 -0.4617027
    12          9 -0.1503822
    13          9 -0.6281268
    14          9  1.3232209
    

    【讨论】:

    • 谢谢,这很有效,基本上是@Kara Woo 在她的编辑中添加的内容
    【解决方案5】:

    我不得不稍微编辑你的数据框:

    set.seed(20)
    subject_id <- as.factor(c(1,2,3,4,4,5,5,6,6,7,8,9,9,9,10))
    variable <- rnorm(15)
    mydata<-as.data.frame(cbind(subject_id, variable))
    

    现在获取多次出现的主题的所有行:

    mydata[duplicated(mydata$subject_id) 
           | duplicated(mydata$subject_id, fromLast = TRUE), ]
    #    subject_id   variable
    # 4           4 -1.3325937
    # 5           4 -0.4465668
    # 6           5  0.5696061
    # 7           5 -2.8897176
    # 8           6 -0.8690183
    # 9           6 -0.4617027
    # 12          9 -0.1503822
    # 13          9 -0.6281268
    # 14          9  1.3232209
    

    编辑:这也可以,使用您的duplicates 向量:

    mydata[mydata$subject_id %in% duplicates, ]
    

    【讨论】:

    • 这行得通,查看“fromLast=TRUE”返回的参数并再次查看帮助文件,我相信我明白为什么。我没有想过帮助文件中的“duplicated() 确定向量或数据框的哪些元素是元素的重复具有较小的下标”。你知道一个函数可以识别向量中的重复项,而不管索引中的位置如何?
    • 谢谢!您使用我的重复向量进行的编辑是我正在寻找的解决方案。尽管现在提供了其他几个答案,但我认为使用 {dplyr} 或 {data.table} 是一种更优雅的方式来完成此任务,因此为了其他读者的利益,我们将选择其中一个作为答案
    猜你喜欢
    • 1970-01-01
    • 2012-12-03
    • 2020-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-11
    • 1970-01-01
    相关资源
    最近更新 更多