如何根据另一个数据框中的值引用一个数据帧中的值?

时间:2012-10-17 16:20:42

标签: r pattern-matching dataframe

我是R的新手,在操作一些环境监测数据时对此问题感到困惑。

我有两个数据集分别记录实际监控时间序列和监控站点信息。我将它们存储在两个数据框monitoringsites中:

monitoring:

                  date       site obs
 1 2001-01-01 10:00:00  riverside  NA
 2 2001-01-01 11:00:00  riverside  52
 3 2001-01-01 12:00:00  riverside  52
 4 2001-01-01 13:00:00  riverside  56
 5 2001-01-01 10:00:00       dorm  52
 6 2001-01-01 11:00:00       dorm  64
 7 2001-01-01 12:00:00       dorm  76
 8 2001-01-01 13:00:00       dorm  80
 9 2001-01-01 10:00:00        kfc  78
10 2001-01-01 11:00:00        kfc  74
11 2001-01-01 12:00:00        kfc  66
12 2001-01-01 13:00:00        kfc  68

sites:

        site       type
 1      DORM   suburban
 2       KFC      urban
 3 RIVERSIDE      rural

我想在site.type中添加一个monitoring列,其中包含从sites中提取的信息,如下所示:

                  date       site obs site.type
 1 2001-01-01 10:00:00  riverside  NA     rural
 2 2001-01-01 11:00:00  riverside  52     rural
 3 2001-01-01 12:00:00  riverside  52     rural
 4 2001-01-01 13:00:00  riverside  56     rural
 5 2001-01-01 10:00:00       dorm  52  suburban
 6 2001-01-01 11:00:00       dorm  64  suburban
 7 2001-01-01 12:00:00       dorm  76  suburban
 8 2001-01-01 13:00:00       dorm  80  suburban
 9 2001-01-01 10:00:00        kfc  78     urban
10 2001-01-01 11:00:00        kfc  74     urban
11 2001-01-01 12:00:00        kfc  66     urban
12 2001-01-01 13:00:00        kfc  68     urban

我在以下命令中尝试了grep()

for (i in 1:nrow(monitoring)) {
  monitoring$site.type[i] <- as.character(sites$type[grep(monitoring$site[i], sites$site, ignore.case = T)])
}

在这个monitoring的小示例集上工作正常。但是,当我将它应用到我的654,525条记录的真实数据集时,它从未停止在具有16 GB RAM的i5-2400计算机上运行...

我试图在stackoverflow上搜索现有的问题并且确实找到了一些答案,为类似的场景提供了相同的解决方案,所以更加困惑的是为什么它在我的情况下不起作用。因此,

  1. 有人可以指出问题所在吗?
  2. 我可以问一下如何在这种情况下避免for循环 不是“时尚”和高效? :)
  3. 非常感谢提前。

2 个答案:

答案 0 :(得分:3)

正如Ben建议的那样,正确的方法是使用merge,但这是一个简单的伎俩:

rownames( sites ) <- tolower( sites$site )

现在,您可以使用sites等密钥访问riverside,例如尝试sites[ "riverside", ]tolower()功能仅用于将RIVERSIDE转换为riverside。因此,你可以做到

monitoring$site.type <- sites[ monitoring$site, "type" ]

答案 1 :(得分:1)

使用Ben建议的merge很容易

monitoring
sites$site <- factor(tolower(sites$site)) # cols are unordered

merge(monitoring, sites, by='site')

# fixing col order...
merge(monitoring, sites, by='site')[,c('date', 'site', 'obs', 'type')]