【问题标题】:Subsetting a data frame based on values specified in another dataset根据另一个数据集中指定的值对数据框进行子集化
【发布时间】:2019-11-27 20:50:21
【问题描述】:

我有一个类似于下面创建的DataSetA 的数据框。观察代表在每个人的长度上对相同的 3 个变量进行的测量。在个人(A、B、C 等)内,每个观察与前一个观察的距离相等。为了澄清,在真实数据中,每个人的长度是不同的。因此,每个变量(Var1Var2Var3)的索引数量相同,但每个人之间不同(Individual A 可能有 50 个观察值,但 Individual B 可能有 70 个) .

我有兴趣比较个体之间每个个体的不同位置开始的等长数据。因此,我凭经验检测每个人体内的单个“兴趣点”(单个索引),并希望收集该点和之前的 9 个点,以便在个人之间进行比较。

我需要对数据进行子集化,最终得到一个新的数据框,其中包含每个人的十个观察值,格式与原始数据框相同。在过去,我通过 Tidyverse(如下所示)对每个人使用过滤器和切片函数来完成此操作,并使用 rbind 将它们组合到新的数据帧中。然而,这样做需要在我的代码中大量重复(和时间),并且我的数据集正在增长。

我想为每个人创建一个单独的对象,该对象具有一行和两列,其中包含个人 ID 和他们“兴趣点”的相应索引。基本上我想说; “如果数据集A 中的id 与数据集B 中的id 匹配,则数据集BID 旁边的数字是我希望R 开始的行的索引在数据集A(兴趣点)中,并在新数据框中返回该行和它之前的九行”。

我不确定 for 循环是否是执行此操作的合适方法,或者是否还有其他方法。任何帮助将不胜感激。

Individuals <- rep(c("A","B","C"), each = 50)

Var1 <- rnorm(50)
Var2 <- rnorm(50)
Var3 <- rnorm(50)

DataSetA <- cbind(Individuals, Var1, Var2, Var3)
DataSetA <- data.frame(DataSetA)

#How I usually filter to achieve what I want:
#The point of interest for Individual A is the 32nd observation taken on
#Individual A, so I need observations 23:32
A <-
  DataSetA%>%
  filter(Individuals == A)%>%
  slice(23:32)
#The point of interest for Individual B is the 35th observation taken on
#Individual B, so I need observations 26:35
#note that this is the 35th observation for that individual (not the 35th observation of the data set)
B <-
  DataSetA%>%
  filter(Individuals == B)%>%
  slice(26:35)
#The point of interest for Individual C is the 16th observation taken on
#Individual B, so I need observations 7:16
C <- 
  DataSetA%>%
  filter(Individuals == C)%>%
  slice(7:16)
#I then have to combine them using rbind
ExtractedData <- rbind(A,B,C)

#Below creates what I would like to use as "dataset B" to tell R what number to start filtering at in DataSetA

Individuals <- c("A","B","C")
PointOfInterest <- c(32,35,16)
DataSetB <- data.frame(Individuals, PointOfInterest)

【问题讨论】:

    标签: r function loops for-loop


    【解决方案1】:

    一种选择是使用map2

    library(dplyr)
    library(purrr)
    map2_df(DataSetB$Individuals, DataSetB$PointOfInterest, ~ 
           DataSetA %>%
               filter(Individuals == .x, row_number() > .y))
    

    如果我们要过滤 9 行,包括 'DatasetB' 中的 'PointOfInterest' 中显示的那一行

     map2_df(DataSetB$Individuals, DataSetB$PointOfInterest, ~ 
           DataSetA %>%
           group_by(Individuals)%>%
           mutate(rn = row_number()) %>% #just to show the row number
                filter(Individuals == .x, between(row_number(), .y-9, .y)))
    #   Individuals        Var1        Var2        Var3 rn
    #1            A -0.50715002 -1.63196034  0.24824287 23
    #2            A -0.50694324  0.99443347 -0.25148466 24
    #3            A  0.26498877  1.59758547 -0.97999740 25
    #4            A  0.59168174 -0.67593906  0.58904189 26
    #5            A -0.28834071  0.50565228 -1.40489489 27
    #6            A -0.52907038  0.86131470 -1.50978892 28
    #7            A -0.17986538  0.74555059 -0.42154441 29
    #8            A -0.93043770  0.94839988  1.28018362 30
    #9            A -2.46745604 -0.27824127 -0.36406006 31
    #10           A -0.05040743  1.13697037 -0.85254191 32
    #11           B  0.08314367 -0.07045269 -0.02063172 51
    #12           B  2.78494703 -0.75031916 -0.90366751 52
    #13           B  0.59528232 -0.09401376  2.14675010 53
    #14           B  0.07766635  0.41274946  0.52784216 54
    

    【讨论】:

    • 我从未使用过地图,但我正在玩这个,它似乎可以工作。我如何告诉它过滤兴趣点减去 9 个数据点?
    • @Ryan 不清楚情况。你能更新一下吗
    • @Ryan 我找不到您的评论。我收到一条关于您的评论的消息,但是在查看这里时,没有评论
    • 抱歉,让我尝试澄清一下(并适当地标记我的代码,我是新站点):如果个人 A 的 PointOfInterest 是个人 A 记录的第 32 个数据点。而个人 B 的 PointOfInterest 是个人 B 记录的第 15 个数据点,我需要 DataSetA %&gt;% filter(Individuals==A)%&gt;%slice(23:32)DataSetA%&gt;%filter(Individuals==B)%&gt;%slice(6:15) 以便每个人只有 PointOfInterest 和 9 个数据点。
    • @Ryan 在这种情况下,您可以将我的代码中的filter 步骤更改为filter(Individuals == .x, between(row_number(), .y-9, .y))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    相关资源
    最近更新 更多