簡體   English   中英

如何在“ R”中有效地子集多個數據幀?

[英]How to subset multiple data frame efficiently in 'R'?

我有一個很大的大氣PM10數據“ NetCDF”文件。 您可以從這里下載。我正在解釋有關我的問題的詳細信息。

此ncdf文件具有8個這樣的變量。

[1] "file ~/Downloads/2012_03_05_PM10_surface.nc has 8 dimensions:"
[1] "data_num   Size: 683016"
[1] "ncl1   Size: 683016"
[1] "obsnum_urban   Size: 250"
[1] "ID_LAT_LON   Size: 3"
[1] "obsnum_road   Size: 33"
[1] "obsnum_background   Size: 5"
[1] "obsnum_rural   Size: 16"
[1] "ncl7   Size: 683016"
[1] "------------------------"
[1] "file ~/Downloads/2012_03_05_PM10_surface.nc has 8 variables:"
[1] "int TMSID[data_num]  Longname:TMSID Missval:NA"
[1] "int TIME[ncl1]  Longname:TIME Missval:NA"
[1] "float PM10[data_num]  Longname:PM10 Missval:1e+30"
[1] "float urban[ID_LAT_LON,obsnum_urban]  Longname:urban Missval:1e+30"
[1] "float road[ID_LAT_LON,obsnum_road]  Longname:road Missval:1e+30"
[1] "float background[ID_LAT_LON,obsnum_background]  Longname:background Missval:1e+30"
[1] "float rural[ID_LAT_LON,obsnum_rural]  Longname:rural Missval:1e+30"
[1] "int TMS_JULIAN[ncl7]  Longname:TMS_JULIAN Missval:NA"

在這里,我的興趣只有4個變量。 他們是:

TIMSID是站點數量(包括城市站點,農村站點,道路,背景等)

urban ::城市站點數[城市是3行250列矩陣。 第1列是城市用地數量,第2列是latidude,第3列是經度。]

TIME ::數據是從2012年3月1日上午1點到2012年5月收集的。“時間”的編碼為YYYYMMDDHH

PM10 ::在每個站點的每個站點測量的每小時顆粒物濃度

從這個ncdf文件中,我已經將2012年3月1日凌晨1點(2012030101)的PM10值僅用於城市站點。 如您所知,TMSID是所有站點的ID,但是我只想為城市站點(而不是農村,道路等)分配子集,因此我只匹配了2012年3月1日凌晨1點的TMSID中的城市ID。僅匯總了1月1月1月城市地區PM10數據。 我使用以下代碼:

library(ncdf)
nc<-open.ncdf("2012_03_05_PM10_surface.nc")
print(nc)

urban<-get.var.ncdf(nc,"urban")
time<-get.var.ncdf(nc,"TIME")
pm10<-get.var.ncdf(nc,"PM10")
tmsid<-get.var.ncdf(nc,"TMSID")
urban<-as.data.frame(t(urban))
colnames(urban)<-c("ID","LAT","LON")

urban311<-lapply(urban$ID,
                 function(x)data.frame(ID=x,time=2012030101,
                                       PM10=pm10[tmsid%in%x &
                                                   time%in%2012030101]))
urban311<-do.call(rbind,urban311)
urban311<-merge(urban311,urban,by="ID")
urban311
urban311<-subset(urban311,select=c("time","ID","LAT","LON","PM10"))

seoul311<-subset(urban311, LAT>=36.8 & LAT <=38 & LON>=126.4 & LON<= 127.3)
rownames(seoul311)<-NULL

在上述代碼的最后兩行中,我僅根據緯度和經度為市區中的特定區域提供了PM10子集。 最后我得到了這樣的數據框。

              time     ID      LAT      LON PM10
    1   2012030101 111121 37.56464 126.9760   42
    2   2012030101 111123 37.57203 127.0050   37
    .
    .
    .
   106  2012030101 831153 37.49195 126.7533   68
   107  2012030101 831154 37.52662 126.8064   57

如您所知,這是3月1日凌晨1.00的數據幀。現在,我想從3月1日到3月7日每小時進行一次相同的工作。 這意味着我要獲取(7 * 24)數據幀。 我如何有效地做到這一點?

請問我是否還有其他問題。 提前致謝。

這里不需要使用lapply 此外,與其獲取7 * 24數據幀,不如將一個具有所有日期的數據幀有意義,然后可以根據需要對其進行子集化。

這全部發生,而不是您的urban311東西。 首先列出我們要保留的所有time

dts.to.get <- seq(as.POSIXct('2012-03-01 01:00'), as.POSIXct('2012-03-07 00:00'), by='1 hour')
# convert to the 2012030101 numeric format you have
dts.number <- as.numeric(format(dts.to.get, '%Y%m%d%H'))

然后確定哪些索引是城市ID並具有適當的時間:

i <- tmsid %in% urban$ID & time %in% dts.number
x <- data.frame(ID=as.vector(tmsid[i]), time=as.vector(time[i]), PM10=as.vector(pm10[i]))

請注意, subset(x, time==2012030101)是您的urban311 x包含您所使用的所有不同的日期時間。

然后,如果要添加LATLON ,請像以前一樣使用merge 請注意,由於每個ID出現7 * 64次,因此會在數據幀中復制168次,因此最好將它們分開。

x <- merge(x, urban, by='ID')

無需做額外的subset(urban311, select=c("time", "ID", "LAT", "LON", "PM10"))因為它們仍然是urban311唯一的列。

如果你真的真的要分手了x成每日期小時一個數據幀,那么你可以做

lapply(unique(x$time), function (tt) subset(df, time == tt))

以獲得數據幀列表,但實際上,這樣做是不值得的。 需要花些時間,並且可以根據需要更快地將其划分為subset

library(ncdf)
nc<-open.ncdf("2012_03_05_PM10_surface.nc")
print(nc)

urban<-get.var.ncdf(nc,"urban")
time<-get.var.ncdf(nc,"TIME")
pm10<-get.var.ncdf(nc,"PM10")
tmsid<-get.var.ncdf(nc,"TMSID")

urban<-as.data.frame(t(urban))
colnames(urban)<- c("ID","LAT","LON")

dates<-seq(as.POSIXct("2012-03-01:01:00"),
           as.POSIXct("2012-03-08:00:00"), by="1 hour")
dates.numeric <-as.numeric(format(dates, "%Y%m%d%H"))

i<-tmsid %in% urban$ID & time %in% dates.numeric
urban1to7<-data.frame(ID=as.vector(tmsid[i]), 
              time= as.vector(time[i]),
              PM10=as.vector(pm10[i]))
urban1to7<-merge(urban1to7,urban,by="ID")
urban311<-subset(urban1to7, time=2012030101)

#urban sites,seoul area,7 days,every hour
seoul1to7<-subset(urban1to7,LAT>=36.8 & LAT<=38 & LON>=126.4 & LON<=127.3)

# make a list where there is (7*24) data frames
lapply(unique(seoul1to7$time), function(x) subset(seoul1to7, time==x))

這樣,我們可以按lapply列出包含(7 * 24)個數據幀的列表。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM