【问题标题】:R - conditionally replace rows in data table [duplicate]R - 有条件地替换数据表中的行[重复]
【发布时间】:2016-04-14 03:41:27
【问题描述】:

我正在尝试有条件地替换数据表中的行值。 请考虑以下数据集摘录:

library(data.table)
txt1 <- "Date Location Measurement Scenario         Var Month    Decade
  1960-01-01  4100103        23.3  CRU3.2 Temperature   Jan 1960-1990
  1960-02-01  4100103        24.1  CRU3.2 Temperature   Feb 1960-1990
  1960-03-01  4100103        23.6  CRU3.2 Temperature   Mar 1960-1990
  1960-04-01  4100103        20.4  CRU3.2 Temperature   Apr 1960-1990
  1960-05-01  4100103        16.2  CRU3.2 Temperature   May 1960-1990
  1960-06-01  4100103        16.5  CRU3.2 Temperature   Jun 1960-1990"

dt <- data.table(read.table(textConnection(txt1), header=TRUE))

这只是一个示例。我的实际数据大约有 250 万行。

如您所见,我对多个位置进行了温度测量。 但是,这些位置是用地理编码而不是名称来标识的,这不是很可读。

因此,我有另一个与地理编码和城市名称相关的数据集:

txt2 <- "GEOCODIG_M, Name
4100103,              Abatiá
4100202,        Adrianópolis
4100301,       Agudos do Sul
4100400, Almirante Tamandaré
4100459,  Altamira do Paraná
4100509,             Altônia"

df <- read.csv(textConnection(txt2),sep=',', header=TRUE)

所以,我需要做的是将dt 中的Location 字段与df 中的GEOCODIG_M 进行比较,并用名称替换地理编码。

这个案例的预期结果是:

        Date    Name Measurement Scenario         Var Month    Decade
  1960-01-01  Abatiá        23.3  CRU3.2 Temperature   Jan 1960-1990
  1960-02-01  Abatiá        24.1  CRU3.2 Temperature   Feb 1960-1990
  1960-03-01  Abatiá        23.6  CRU3.2 Temperature   Mar 1960-1990
  1960-04-01  Abatiá        20.4  CRU3.2 Temperature   Apr 1960-1990
  1960-05-01  Abatiá        16.2  CRU3.2 Temperature   May 1960-1990
  1960-06-01  Abatiá        16.5  CRU3.2 Temperature   Jun 1960-1990

使用数据表执行此操作的最佳方法是什么?

【问题讨论】:

  • 仅供参考,您也可以使用fread(txt1)。这里的合并分配非常标准:dt[df, on=c(Location="GEOCODIG_M"), Name := i.Name ]
  • @Frank 感谢您的建议。但是,在我的实际数据上尝试此操作时,我收到一个错误:Error in bmerge(i, x, leftcols, rightcols, io, xo, roll, rollends, nomatch, : x.'Location' is a factor column being joined to i.'GEOCODIG_M' which is type 'integer'. Factor columns must join to factor or character columns. 如何调整您的代码来克服这个问题?
  • 您可以在合并之前覆盖这两个地方的列,例如DT[, Location := as.character(Location)]df$GEOCODIG_M = as.character(df$GEOCODIG_M)
  • 成功了,谢谢!您能发表您的评论作为答案,以便我接受吗?
  • 酷,很高兴它成功了。我认为标记的欺骗很好地涵盖了它,但如果您不同意,我将取消标记欺骗并发布另一个答案。

标签: r replace data.table rows


【解决方案1】:

有几种方法可以解决这个问题。

您可以简单地创建一个新的“名称”变量,使用matchtxt2 中查找匹配行。

txt1$Name <- txt2$Name[match(txt1$Location, txt2$GEOCODIG_M)]

或者,您可以合并两个数据集

txt3 <- merge(txt1, txt2, by.x = 'Location', by.y = 'GEOCODIG_M', all.x = TRUE)

【讨论】:

  • 谢谢,但我宁愿不创建任何其他表,因为我原来的表是 1.5GB 的 RAM 大小。这就是为什么我宁愿坚持使用数据表解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-01
  • 2019-01-02
  • 1970-01-01
  • 2017-01-30
  • 2018-11-07
  • 2016-04-25
  • 1970-01-01
相关资源
最近更新 更多