【问题标题】:Subsetting, dat[13:24,2] does not return what I expected in this case子集,dat[13:24,2] 在这种情况下没有返回我所期望的
【发布时间】:2015-01-27 01:21:54
【问题描述】:

我正在尝试在 R 中解决子集化问题。

我有一个数据集,其中包含两个名为 DietBodyweight 的列。 行1:12 是控制观察值,我想获得控制组Bodyweight 列的平均值。

所以我用这个:mean(dat[1:12,2])

然后我想找出有多少非对照观察(第 13:24 行)小于对照观察(第 1:12 行)的平均值。

所以我使用了这个: dat[dat[13:24,2] < mean(dat[1:12,2]), ]

这给了我这个:

   Diet Bodyweight
3  chow      24.04
10 chow      20.10
12 chow      26.25
15   hf      22.80
22   hf      21.90
24   hf      20.73

但我期待它返回这样的内容,其中不包括 1:12 行:

   Diet Bodyweight
15   hf      22.80
22   hf      21.90
24   hf      20.73

我如何做到这一点?

*edit: dput() 结果:

> dput(dat)
structure(list(Diet = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L), .Label = c("chow", "hf"), class = "factor"), Bodyweight = c(21.51, 
28.14, 24.04, 23.45, 23.68, 19.79, 28.4, 20.98, 22.51, 20.1, 
26.91, 26.25, 25.71, 26.37, 22.8, 25.34, 24.97, 28.14, 29.58, 
30.92, 34.02, 21.9, 31.53, 20.73)), .Names = c("Diet", "Bodyweight"
), class = "data.frame", row.names = c(NA, -24L))

【问题讨论】:

  • 请使用dput()发布可重现的示例

标签: r indexing dataframe


【解决方案1】:

分两步完成。首先获取目标行,然后应用逻辑选择:

> dat[ 13:24, ][dat[13:24,2] < mean(dat[1:12,2]), ]
   Diet Bodyweight
15   hf      22.80
22   hf      21.90
24   hf      20.73

您可以将对 "[" 的调用链接在一起。对“[”的第二次调用只是选择具有 12 项逻辑向量的行,但由于它是从同一组值创建的,因此它是“同步的”。

【讨论】:

    【解决方案2】:

    如果您不知道行号,也可以使用名称和值。

    df[with(df, Diet == "hf" & Bodyweight < mean(Bodyweight[Diet == "chow"])), ]
    #    Diet Bodyweight
    # 15   hf      22.80
    # 22   hf      21.90
    # 24   hf      20.73
    

    【讨论】:

    • 谢谢,这可能是将来更好的方法。但目前这超出了我的能力范围。
    【解决方案3】:

    如果您不知道行号并且不知道其他测试变量的名称(在这种情况下您的测试变量不止“hf”)但知道“chow”饮食是您的控制,您可以这样做:

    library(dplyr)
    df %>% filter(Diet != "chow", Bodyweight < mean(Bodyweight[Diet == "chow"]))
    

    返回:

    #  Diet Bodyweight
    #1   hf      22.80
    #2   hf      21.90
    #3   hf      20.73
    

    【讨论】:

      【解决方案4】:

      要显着提高易读性,请对数据集进行分区 - 如果您在很多列上进行大量控制与非控制比较,这将有所帮助。魔术行索引被认为不好 - 太容易出错了:

      # Add a column to split into control/non-control
      dat$control <- c(rep(T,12),rep(F,12))
      
      # Get aliases for those partitions... (this makes a copy of the whole df)
      dat_n <- dat[dat$control==F,]
      dat_c <- dat[dat$control==T,]
      
      # Now the expression is waaay more legible and self-explanatory
      dat_n[ dat_n$Bodyweight < mean(dat_c$Bodyweight) ,]
      #    Diet Bodyweight control
      # 3    hf      22.80   FALSE
      # 10   hf      21.90   FALSE
      # 12   hf      20.73   FALSE
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-05-30
        • 1970-01-01
        • 2016-11-06
        • 2021-12-11
        • 2018-05-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多