我是R的新手,在操作一些环境监测数据时对此问题感到困惑。
我有两个数据集分别记录实际监控时间序列和监控站点信息。我将它们存储在两个数据框monitoring
和sites
中:
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上搜索现有的问题并且确实找到了一些答案,为类似的场景提供了相同的解决方案,所以更加困惑的是为什么它在我的情况下不起作用。因此,
for
循环
不是“时尚”和高效? :)非常感谢提前。
答案 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')]