等同于第一/最后。 R中的SAS处理

时间:2018-08-03 17:48:21

标签: r

我确实在此(R equivalent of .first or .last sas operator)上找到了一个线索,但并未完全回答我的问题。

我来自SAS背景,例如,当您的患者ID具有多个不同的值,并且您只想为每个ID的另一个变量保留具有最小值/最大值的行时,这是一个常见的操作。例如,我可能具有每个ID都有特定医疗问题的日期的数据,并且我想要一个仅包含每个患者的第一个/最后一个问题日期的数据集。

这是一个简单的示例,可以让我了解所需的信息,但是我想知道是否有更好的方法可以做到。我按ID排序,然后计数,我只想保留每个ID计数最大的行。

testdata<-data.frame(id=c(1,1,1,2,3,3,4,3,4,4,4),
                 count=c(5,9,2,6,16,12,0,11,8,8,7))

library(dplyr)

testdata2<-arrange(testdata,id,count)

testdata3<-cbind(testdata2,!duplicated(testdata2$id,fromLast=TRUE))

testdata4<-subset(testdata3,testdata3[,3]=='TRUE')[,-3]


> testdata4
    id count
3   1     9
4   2     6
7   3    16
11  4     8

是否有更紧凑的方法来做到这一点?

谢谢。

1 个答案:

答案 0 :(得分:0)

do.call(rbind.data.frame,
        c(by(testdata, testdata$id, function(d) d[c(1L,nrow(d)),]), stringsAsFactors=FALSE))
#       id count
# 1.1    1     5
# 1.3    1     2
# 2.4    2     6
# 2.4.1  2     6
# 3.5    3    16
# 3.8    3    11
# 4.7    4     0
# 4.11   4     7

打破现状:

  • d[c(1L,nrow(d)),]返回数据帧的第一行和最后一行。 (我假设框架已经适当订购了。)
  • by(testdata, testdata$id, function通过$id将较大的帧分解为较小的帧,并将每个较小的帧传递给匿名函数。这将返回每个返回值的by-列表。
  • do.call(rbind.data.frame,抓取列表并将它们重新绑定在一起成为一个框架。由于默认设置是使用factor,因此我添加了stringsAsFactors=FALSE

如果要使用dplyr,可以执行以下操作:

library(dplyr)
group_by(testdata, id) %>%
  slice(c(1,n())) %>%
  ungroup()
# # A tibble: 8 × 2
#      id count
#   <dbl> <dbl>
# 1     1     5
# 2     1     2
# 3     2     6
# 4     2     6
# 5     3    16
# 6     3    11
# 7     4     0
# 8     4     7

其中n()dplyr管道中的特殊功能,它返回该(可选分组)帧中的行数。