0

我必须在此数据集 (dat) 上进行一组随天而变的选择,该数据集由物种 (sp)、天 (天,在 POSIXct 中) 和面积 (ar) 组成:

sp  day         ar
A   1-Jan-00    2
B   1-Jan-00    6
C   2-Jan-00    2
A   2-Jan-00    1
D   2-Jan-00    4
E   2-Jan-00    12
F   3-Jan-00    8
A   4-Jan-00    3
G   4-Jan-00    2
B   4-Jan-00    1

我需要对物种“A”出现的位置进行子集化。但是,要选择的区域会因天而异,由该矩阵 (dat.ar) 给出:

day       ar.select
1-Jan-00    (1,6)
2-Jan-00    (1,12)
3-Jan-00    (4,8)
4-Jan-00    (3,12)

更具体地说,对于物种“A”出现的区域,在 00 年 1 月 1 日,我只需要区域 1 和 6。对于 00 年 2 月,区域 1 和 12,依此类推。作为示例,此示例的此选择所需的输出如下所示:

sp  day        ar
A   2-Jan-00    1
A   4-Jan-00    3

我在获得 for 循环方面没有取得多大成功,因为我仍在尝试学习 R 中的语义。总而言之,对必须做什么有一个粗略的想法,但仍在努力学习该语言。这是我认为应该去哪里的草图:

dat1 = with(dat,sapply(day[sp=="A" & dat.ar$day.s[i] ], 
function(x) ar == (ar[sp=="A" & day == x]==dat.ar$ar.select[j]) 
final=dat[rowSums(dat1) > 0, ]

我相信我必须适合一个 for 循环,它将通过 dat.ar,指定要在 dat 中选择的区域。但是,尽管我努力尝试 for 循环,但我还没有接近。我什至不确定结合 sapply 和 for 循环是否是解决此问题的正确方法。如果有人希望重现该问题:

sp=c("A","B","C","A","D","E","F","A","G","B")
day=c("1-Jan-00", "1-Jan-00", "2-Jan-00", "2-Jan-00", "2-Jan-00", 
"2-Jan-00", "3-Jan-00", "4-Jan-00", "4-Jan-00", "4-Jan-00")
day=as.POSIXct(day, format="%d-%b-%y")
ar=c(2,6,2,1,4,12,8,3,2,1)
dat= as.data.frame(cbind(sp, day, ar)) 

day.s=c("1-Jan-00", "2-Jan-00", "3-Jan-00", "4-jan-00")
day.s=as.POSIXct(day.s, format="%d-%b-%y")
a.s=c(1,1,4,3)
a.e=c(6,12,8,12)
ar.select=paste(a.s, a.e, sep=",")
dat.ar=cbind(day.s, ar.select)

任何帮助深表感谢。

4

2 回答 2

2

您可以将条件表合并到原始数据集并有条件地过滤它们。将 a1 和 a2 视为您的 sp 和 day 值,将 obs 视为您的 ar 值。

library(data.table)
dataset <- data.table(
a1 = c("A","B","C","B","A","A","A","A"),
a2 = c("P","Q","Q","Q","R","R","P","Q"),
obs = c(3,2,3,4,2,4,8,0)
)

constraints <- data.table(
a1 = c("A","B","C","A","B","C","A","B","C"),
a2 = c("P","P","P","Q","Q","Q","R","R","R"),
lower = c(1,2,3,4,3,2,3,2,5),
upper = c(6,4,5,7,5,6,5,3,7)
)


checkingdataset <- merge(dataset,constraints, by = c("a1","a2"), all.x = TRUE)

checkingdataset[obs <= upper & obs >= lower, obs.keep := TRUE]


#   a1 a2 obs lower upper obs.keep
#1:  A  P   3     1     6    TRUE
#2:  A  P   8     1     6      NA
#3:  A  Q   0     4     7      NA
#4:  A  R   2     3     5      NA
#5:  A  R   4     3     5    TRUE
#6:  B  Q   2     3     5      NA
#7:  B  Q   4     3     5    TRUE
#8:  C  Q   3     2     6    TRUE
于 2013-09-26T19:24:21.670 回答
2

首先,我不会as.data.frame(cbind(...))用来制作你data.frame的 s。其次,我将创建dat.ar与您创建的结构大致相同的结构dat。第三,然后我会使用它merge来获得您正在寻找的结果。

dat <- data.frame(sp=c("A","B","C","A","D","E","F","A","G","B"),
                  day=c("1-Jan-00", "1-Jan-00", "2-Jan-00", "2-Jan-00", 
                        "2-Jan-00", "2-Jan-00", "3-Jan-00", "4-Jan-00", 
                        "4-Jan-00", "4-Jan-00"),
                  ar=c(2,6,2,1,4,12,8,3,2,1))
dat$day <- as.POSIXct(dat$day, format="%d-%b-%y")

day.s <- c("1-Jan-00", "2-Jan-00", "3-Jan-00", "4-jan-00")
day.s <- as.POSIXct(day.s, format="%d-%b-%y")
a.s <- c(1,1,4,3)
a.e <- c(6,12,8,12)
ar.select <- paste(a.s, a.e, sep=",")
dat.ar <- data.frame(sp = "A", day = day.s, ar = ar.select)

dat.ar <- cbind(dat.ar[-3], 
                read.csv(text = as.character(dat.ar$ar), header = FALSE))
library(reshape2)
dat.ar <- melt(dat.ar, id.vars=1:2, value.name="ar")
dat.ar
#   sp        day variable ar
# 1  A 2000-01-01       V1  1
# 2  A 2000-01-02       V1  1
# 3  A 2000-01-03       V1  4
# 4  A 2000-01-04       V1  3
# 5  A 2000-01-01       V2  6
# 6  A 2000-01-02       V2 12
# 7  A 2000-01-03       V2  8
# 8  A 2000-01-04       V2 12

merge(dat, dat.ar)
#   sp        day ar variable
# 1  A 2000-01-02  1       V1
# 2  A 2000-01-04  3       V1

当然,我只是建议你dat.ar一开始就以更友好的方式制作你的对象。如果您稍后要将它们分开,为什么还要将它们粘贴在一起?;)

dat.ar <- data.frame(sp = "A", 
                     day = c("1-Jan-00", "2-Jan-00", "3-Jan-00", "4-jan-00"),
                     a.s = c(1,1,4,3), a.e = c(6,12,8,12))
dat.ar$day <- as.POSIXct(dat.ar$day, format="%d-%b-%y")

library(reshape2)
dat.ar <- melt(dat.ar, id.vars=1:2, value.name="ar")
于 2013-09-26T19:25:58.570 回答