Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/75.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R-保留由多个变量确定的每个组的第一个观察值(Stata等效“bys var1 var2:如果”u n==1“则保留)_R_Stata - Fatal编程技术网

R-保留由多个变量确定的每个组的第一个观察值(Stata等效“bys var1 var2:如果”u n==1“则保留)

R-保留由多个变量确定的每个组的第一个观察值(Stata等效“bys var1 var2:如果”u n==1“则保留),r,stata,R,Stata,因此,我目前在R中面临一个问题,我确切地知道如何在Stata中处理这个问题,但在R中已经浪费了两个多小时 使用下面的data.frame,我想要的结果是准确地获得每组的第一个观察值,而组由多个变量组成,并且必须按另一个变量排序,即data.frame mydata通过以下方式获得: id <- c(1,1,1,1,2,2,3,3,4,4,4) day <- c(1,1,2,3,1,2,2,3,1,2,3) value <- c(12,10,15,20,40,30,22,24,1

因此,我目前在R中面临一个问题,我确切地知道如何在Stata中处理这个问题,但在R中已经浪费了两个多小时

使用下面的data.frame,我想要的结果是准确地获得每组的第一个观察值,而组由多个变量组成,并且必须按另一个变量排序,即data.frame mydata通过以下方式获得:

id <- c(1,1,1,1,2,2,3,3,4,4,4)
day <- c(1,1,2,3,1,2,2,3,1,2,3)
value <- c(12,10,15,20,40,30,22,24,11,11,12)
mydata <- data.frame(id, day, value)
通过仅保留具有一个或多个重复组标识符的行中的一行(此处仅为
行[1]:(id,day)=(1,1))
,首先对值进行排序(以便保留具有最低值的行)

在Stata,这将是:

bys id day (value): keep if _n == 1
我找到了一个,如果我首先生成一个组标识符,它会正确地执行此操作:

mydata$id1 <- paste(mydata$id,"000",mydata$day, sep="")  ### the single group identifier

myid.uni <- unique(mydata$id1)
a<-length(myid.uni)

last <- c()

for (i in 1:a) {
  temp<-subset(mydata, id1==myid.uni[i])
  if (dim(temp)[1] > 1) {
    last.temp<-temp[dim(temp)[1],]
  }
  else {
    last.temp<-temp
  }
  last<-rbind(last, last.temp)
}

last

mydata$id1我会订购
data.frame
,在这一点上,您可以通过
查看:

mydata <- mydata[with(mydata, do.call(order, list(id, day, value))), ]

do.call(rbind, by(mydata, list(mydata$id, mydata$day), 
                  FUN=function(x) head(x, 1)))

或者,从零开始,您可以按以下方式使用
data.table

DT <- data.table(id, day, value, key = "id,day")
DT[, n := rank(value, ties.method="first"), by = key(DT)][n == 1]

DT包dplyr使这类事情变得更容易

library(dplyr)
mydata %>% group_by(id, day) %>% filter(row_number(value) == 1)
请注意,此命令在R中比在Stata中需要更多的内存:在R中,创建数据集的新副本,而在Stata中,行被就地删除。

使用data.table,假设
mydata
对象已按您所需的方式排序,另一种方法是:

library(data.table)
mydata <- data.table(my.data)
mydata <- mydata[, .SD[1], by = .(id, day)]
库(data.table)
mydata%
解组()

如果不将
ungroup()
添加到末尾,dplyr的分组结构仍将存在,并且可能会打乱后续的一些功能。

使用的替代方法是:完成任务,但所用的时间与我最初发布的代码一样长。我将不得不让IT人员安装data.table来查看这一点,如果效果更好,我将在稍后与您联系。@iraserd,我也很难相信这些方法中的任何一种都需要1.5个小时。你能添加更多关于你的数据的信息吗?嗯,我在大约15分钟后放弃了我最初发布的for-loop方法,到那时它已经处理了大约12k的80k个观测值。@Anada Mahto,好的,所以对于我的数据集的一个小的子样本,你的所有3个备选方案都工作得很好。然而,在完整的数据集(大约500k个观测值)上,by()和DT[]似乎比ave()花费的时间要长得多。Ave()大约5分钟后才结束,而我分别在大约10分钟后通过()和DT[]中止。这对我来说是正确的答案,谢谢@伊拉瑟德,我觉得这很奇怪。“data.table”包应该非常高效。您有多少“id”变量的唯一组合?在我对500k
data.frame
的测试中,“data.table”方法我得到了约1分钟,而
ave
方法我得到了约2分钟。我是一个Stata人,但我不认为通过暗示R是差劲的来吸引R用户,即使是对于一个非常具体的详细任务。最好是暗示一定有一个整洁的R方法来做,只是你没有识别它。@NickCox,我不是有意侮辱R,如果这是听起来的话。在过去的两周里,我一直在从Stata进行迁移,但仍在努力获得正确的基本功能。对于迁移的初学者来说,虽然可以在R中有效地使用
for
循环,但如果这是您的第一个选择,它可能不是最有效的方法。@iraserd无疑;我只是建议如何影响人们并鼓励他们回答你的问题。这是什么%>%?错误结果:找不到已加载库(dplyr)的函数“%>%”。是因为我还在运行3.0.2吗?可能吧。它将对象放在左边,作为函数的第一个参数放在右边。第一行相当于slice(arrange(group_by(mydata,id,day),value),1)
Ranks <- with(mydata, ave(value, id, day, FUN = function(x) 
  rank(x, ties.method="first")))
mydata[Ranks == 1, ]
library(dplyr)
mydata %>% group_by(id, day) %>% filter(row_number(value) == 1)
library(data.table)
mydata <- data.table(my.data)
mydata <- mydata[, .SD[1], by = .(id, day)]
library(dplyr)
mydata <- mydata %>%
  group_by(id, day) %>%
  slice(1) %>%
  ungroup()