【问题标题】:A loop for subsetting with which in data frame for another dataframe?用于对另一个数据帧的数据帧进行子集化的循环?
【发布时间】:2014-02-21 14:41:09
【问题描述】:

我搜索了很多类似Subsetting a dataframe in R by multiple conditions这样的帖子,关于选择“哪个”功能来选择值数据框数据框,但找不到其他解决方案。问题如下:

我有以下包含数千个案例的数据集:

> head(Datos)
   tipo         estacion     hora  usos
 1 hábil         A.SANIN      X4    11
 2 hábil        ALAMOS        X4     4
 3 hábil        AMANECER      X4    45
 4 hábil       AMERICAS       X4     2
 5 hábil       ATANASIO       X4    10
 6 hábil       BELALCAZAR     X4     5
 .    .                       .     .
 .    .                       .     .
 .    .                       .     .

上面数据帧子集的变量是“usos”变量“tipo”取值:“hábil”、“Sábado”和“Festivo”。变量“estacion”有 60 个级别,变量“hora”有 22 个值:x4, x5, x6, ... x23。由于我需要根据 "tipo" 、 "estacion" 和 "hora" 的所有组合计算四分位数,我使用 "aggregate" 函数并计算临界值,所以我得到了这个:

  > head(todo)
    Group.1  Group.2      Group.3      y1    y2
 1   hábil      X4         A.SANIN      1.5   21.5
 2   Sábado     X4         A.SANIN      4.0   12.0
 3   Festivo    X4         A.SANIN      0.0   0.0
 4   hábil      X5         A.SANIN      66.0  130.0
 5   Sábado     X5         A.SANIN      40.0  96.0
 6   Festivo    X5         A.SANIN      7.5   43.5
 .                      .
 .                      .
 .                      .

每一行都是不同的情况,值y1和y2是我的临界值​​。需要,根据我选择的dataframe“todo”的值y1和y2取值小于y1或者大于dataframe“Datos”的变量“usos”的y2。但在一个循环中,数据框“todo”上有 3480 个组合,即 3480 行。并将其存储在另一个矩阵中。

例如,对于第一种情况如下:

print(which(subset(Datos$usos,Datos$tipo=="hábil"&Datos$hora=="X4"&Datos$estacion=="A.SANIN")<todo$y1[1] | subset(Datos$usos,Datos$tipo=="hábil"&Datos$hora=="X4"&Datos$estacion=="A.SANIN")>todo$y2[1]))

我需要对数据框“全部”的所有行执行此操作,并将其应用于“使用”数据框“数据”。

谢谢!

【问题讨论】:

    标签: r


    【解决方案1】:

    我有点难以理解你在说什么,但我认为这就是你想要的。首先,将todoDatos 合并:

    # Rename the columns of todo to match Datos
    names(todo)<-c('tipo','hora','estacion','y1','y2')
    # Merge the two.
    Datos.y.todo<-merge(Datos,todo)
    

    现在,您可以轻松地根据您的条件进行子集化:

    with(Datos.y.todo, Datos.y.todo[usos<y1 | usos>y2, ])
    

    我相信以上回答了您的问题。让我用你的数据来说明。

    # Load in your data.
    Datos<-read.table(textConnection('tipo         estacion     hora  usos
    1 hábil         A.SANIN      X4    11
    2 hábil        ALAMOS        X4     4
    3 hábil        AMANECER      X4    45
    4 hábil       AMERICAS       X4     2
    5 hábil       ATANASIO       X4    10
    6 hábil       BELALCAZAR     X4     5'),header=TRUE)
    
    todo<-read.table(textConnection('Group.1  Group.2      Group.3      y1    y2
    1   hábil      X4         A.SANIN      1.5   21.5
    2   Sábado     X4         A.SANIN      4.0   12.0
    3   Festivo    X4         A.SANIN      0.0   0.0
    4   hábil      X5         A.SANIN      66.0  130.0
    5   Sábado     X5         A.SANIN      40.0  96.0
    6   Festivo    X5         A.SANIN      7.5   43.5'),header=TRUE)
    

    正如您所提到的,Datos 重复包含许多相同的“案例”,所以让我们在 Datos 中添加两行以使示例更清晰:

    Datos<-rbind(Datos,data.frame(tipo=c('hábil','Sábado'),estacion='A.SANIN',hora='X4',usos=c('23','3')))
    #     tipo   estacion hora usos
    # 1  hábil    A.SANIN   X4   11 # This one neither below y1 or above y2
    # 2  hábil     ALAMOS   X4    4
    # 3  hábil   AMANECER   X4   45
    # 4  hábil   AMERICAS   X4    2
    # 5  hábil   ATANASIO   X4   10
    # 6  hábil BELALCAZAR   X4    5
    # 7  hábil    A.SANIN   X4   23 # This one is above y2 (21.5), so we want to find it.
    # 8 Sábado    A.SANIN   X4    3 # This one is below y1 (4.0), so we want to find it. 
    

    现在运行我之前给你的代码:

    # Rename the columns of todo to match Datos
    names(todo)<-c('tipo','hora','estacion','y1','y2')
    # Merge the two.
    Datos.y.todo<-merge(Datos,todo)
    # Notice how the y1 and y2 values are now repeated for easy comparison.
    #     tipo estacion hora usos  y1   y2
    # 1  hábil  A.SANIN   X4   11 1.5 21.5 # We don't want this row.
    # 2  hábil  A.SANIN   X4   23 1.5 21.5 # We want this row.
    # 3 Sábado  A.SANIN   X4    3 4.0 12.0 # We want this row.
    

    最后,你过滤你想要的行:

    with(Datos.y.todo, Datos.y.todo[usos<y1 | usos>y2, ])
    
    #     tipo estacion hora usos  y1   y2
    # 2  hábil  A.SANIN   X4   23 1.5 21.5
    # 3 Sábado  A.SANIN   X4    3 4.0 12.0
    

    【讨论】:

    • 不是我的朋友。我想我需要向你解释更多。想法是,数据框“todo”有 3480 行。每一行都是一个案例,例如第一个案例是 (hábil,X4,A.SANIN)。但是这种情况,很多时候都在数据框“Datos”中,例如“todo”的第一个 y1 和 y2 是 1.5 和 21.5。所以我在“Datos”中搜索案例(hábil,X4,A.SANIN)并且有很多行。看?所以我查找“Datos”的每一行“usos”如何,如果它小于 y1 或大于 y2,则使用函数 which 报告该行。
    • 您是否尝试过数据上的代码?我已经更新了我的答案,以说明每个步骤是如何工作的。你能解释一下我的代码对你的数据不起作用的具体情况吗?
    • 顺便问一下,这是哥伦比亚卡利的过境数据吗?它在某个地方公开可用吗?
    猜你喜欢
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    • 2020-05-01
    • 2021-10-16
    • 1970-01-01
    • 2020-06-17
    相关资源
    最近更新 更多