【问题标题】:How to optimise these loops in R如何在 R 中优化这些循环
【发布时间】:2014-01-17 01:35:21
【问题描述】:

我正在清理数据,结果出现了很多 for 循环。由于我的数据集有超过 600 万行,这对我来说有点问题,但我不知道如何避免它。

我的数据集(称为 sentencing.df)的示例如下:

    Ethnicity     PersonNumber

    Caucasian     1
    Caucasian     1
    Unknown       1
    Indian        2
    Indian        2

我想在同一个人编号内进行比较 - 例如,我想知道每个个人编号的种族是否相同(如果存在错误条目,则更改它们)。我的代码使用 for 循环,看起来像这样:

PersonListRace <- unique(sentencing.df[sentencing.df$ethnicity == "UNKNOWN",]$PersonNumber) 
PersonListRace <- as.numeric(as.character(PersonListRace))
 # vector of person numbers for those with ethnicity UNKNOWN

for (i in 1:100) {
  race <- sentencing.df[sentencing.df$PersonNumber == PersonListRace[i],]$ethnicity
    # creates a vector of unique ethnicities for that person
  if (length(unique(race)) != 2) {next}
    # excludes those who only have UNKNOWN or who have UNKNOWN plus multiple ethnicities
  else {
   label <- as.character(unique(race[which(race != "UNKNOWN")]))
   sentencing.df[sentencing.df$PersonNumber == PersonListRace[i],]$ethnicity <- label
  }
}

然后我的所有其他变量都有类似的东西,并且 for 循环运行时间太长。我查看了网站上的其他一些问题和答案,但我的主要问题是我无法找到一种方法,只在同一个人编号内比较不同变量,而不使用 for 循环。

任何能帮助我在实际时间范围内实现目标的东西都将不胜感激:)

【问题讨论】:

  • 如果 PersonListRace 是一个因素,那么这是错误的:PersonListRace &lt;- as.numeric(PersonListRace)。应该是PersonListRace &lt;- as.numeric(as.character(PersonListRace))。您的其余代码没有用自然语言很好地描述,而且您对 R 的命令太弱而无法理解,无论如何对我来说。请用英语描述什么是欲望。几乎可以肯定有更有效的方法可用。例如,多数票是否是“正确”的仲裁者,以及如何处理平局。
  • 对不起,如果很难理解 - 我对 R 还比较陌生,并且边走边学。除了我所说的之外,我不确定如何解释我需要什么。我的最终目标是为一个人使用已知的种族 - 例如。第 1 个人的白种人 - 填写其他条目中的空白 - 所以将第 1 个人的“未知”种族也更改为“白种人”。我的问题是我需要比较每个人的种族才能做到这一点,并且如果没有 for 循环,我无法弄清楚如何做到这一点。

标签: r optimization for-loop vectorization


【解决方案1】:

评论中没有解决我的担忧,因此我将仅举这个例子来充分代表问题的复杂性(尽管我的经验是事情很少这么简单);

dat <- read.table(text="Ethnicity     PersonNumber
     Caucasian     1
     Caucasian     1
     Unknown       1
     Indian        2
     Indian        2", header=TRUE)
 dat$TrueEth <- with( dat, ave(Ethnicity, PersonNumber, 
                               FUN=function(perE){
                                              unique( perE[perE != "Unknown"] ) } ) )

> dat
  Ethnicity PersonNumber   TrueEth
1 Caucasian            1 Caucasian
2 Caucasian            1 Caucasian
3   Unknown            1 Caucasian
4    Indian            2    Indian
5    Indian            2    Indian

悬而未决的问题是如何处理多个种族值,如果答案是多数规则,如果存在相同数量的未知数,该怎么办。

【讨论】:

  • 啊,我明白你现在在问什么了。我对这两个查询都有答案,目前由单独的 for 循环处理,尽管也许有更好的方法。我实际上有两个变量,种族1 和种族2。如果一个种族 > 80% 的条目(不包括未知),则成为种族 1,种族 2 为 NA。否则,如果有两个种族(不包括未知)分别占该人条目的 20% 以上(例如 75-25 分),最常见的是 eth1,其次是最常见的 eth2。如果两个标准都不满足,则一切都变得未知。
  • 嗯,虽然我现在看到了一些问题。
猜你喜欢
  • 1970-01-01
  • 2018-09-16
  • 2021-11-04
  • 2016-02-16
  • 2012-07-02
  • 2014-09-07
  • 2011-05-30
相关资源
最近更新 更多