根据两个因子级别删除行

时间:2014-01-10 14:15:49

标签: r dataframe data.table

我遇到的问题与此question非常相似,但我的数据按两个级别分组。

str(dt)
'data.frame':   202206 obs. of  4 variables:
$ cros : int  -205 -200 -195 -190 -185 -180 -175 -170 -165 -160 ...
$ along: Factor w/ 113 levels "100","101","102",..: 1 1 1 1 1 1 1 1 1 1 ...
$ alti : num  1.61 1.6 1.6 1.6 1.6 1.59 1.59 1.59 1.59 1.58 ...
$ year : Factor w/ 6 levels "1979","1983",..: 1 1 1 1 1 1 1 1 1 1 ...

head(dt)
cros along alti year
-205   100 1.61 1979
-200   100 1.60 1979
-195   100 1.60 1979
-190   100 1.60 1979
-185   100 1.60 1979
-180   100 1.59 1979

这些数据是来自不同横断面的信息,这些横断面是变量沿着横断面,它们每隔5米测量一次,这是变量高度变量alti的变量。这是他们多年来所做的,但有时这个断面在某一年更长。所以我想删除那些没有全年测量的交叉点的行。

对于我的数据集,我有一个因子(along)有113个级别,在该因子中我有因子year有6个级别。在这些值中,我有x(along)和y(alti),我想对这一年进行分析,但多年来x必须是相同的值。我希望因子cros删除years的每个因素along都不会出现的值。

我使用的代码是:

require(data.table)
dt <- as.data.table(total)
tt <- dt[,length(unique(along,year)),by=cros]
tt <- tt[V1==max(V1)]
test <-dt[cros %in% tt$cros]

但我没有得到正确的结果。我可以想象独特(沿着,年)不是使用分组数据的正确方法。但是我不知道该怎么做。

这里的Oke更清楚我想要什么

> df <- data.frame(along =       c(10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,12,12), year = c(20,20,20,25,25,25,21,21,20,20,25,25,25,21,21,21,20,20,20,20,25,25,25,25,25,21,21,21,21), cros = c(11,12,13,11,12,13,11,12,11,12,11,12,13,11,12,13,14,15,16,17,14,15,16,17,18,12,13,14,15), value = ceiling(rnorm(29)*10))
> df
   along year cros value
   10    20   11    -3
   10    20   12     5
   10    20   13   -22
   10    25   11    -9
   10    25   12    -3
   10    25   13    -8
   10    21   11    -8
   10    21   12    -8
   11    20   11     7
   11    20   12    -4
   11    25   11    -6
   11    25   12     9
   11    25   13    -5
   11    21   11     6
   11    21   12    17
   11    21   13    -5
   12    20   14   -16
   12    20   15   -17
   12    20   16   -18
   12    20   17    -3
   12    25   14   -18
   12    25   15   -11
   12    25   16    -1
   12    25   17     6
   12    25   18    14
   12    21   12    -3
   12    21   13    19
   12    21   14    16
   12    21   15     7

这就是我希望它看起来的样子,因此删除了for tran transect所有年份都没有出现的cros(x)值。

   along year cros value
    10    20   11    -3
    10    20   12     5
    10    25   11    -9
    10    25   12    -3
    10    21   11    -8
    10    21   12    -8
    11    20   11     7
    11    20   12    -4
    11    25   11    -6
    11    25   12     9
    11    21   11     6
    11    21   12    17
    12    20   14   -16
    12    20   15   -17
    12    25   14   -18
    12    25   15   -11
    12    21   14    16
    12    21   15     7

2 个答案:

答案 0 :(得分:1)

这是一种做法。找到您要保留的所有along,cros条目,然后将它们合并:

dt = data.table(df)

# find the intersections; run in pieces to see what's going on here
to.keep = dt[, list(list(unique(cros))), by = list(along, year)][,
               list(cros = Reduce(intersect, V1)), by = along]

# set the keys to merge together
setkey(to.keep, along, cros)
setkey(dt, along, cros)

# final result
res = to.keep[dt, nomatch = 0]

# optionally, you can order and rearrange columns
setkey(res, along, year, cros)[, names(dt), with = F]
#    along year cros value
# 1:    10   20   11    11
# 2:    10   20   12     7
# 3:    10   21   11    -4
# 4:    10   21   12     9
# 5:    10   25   11   -16
# 6:    10   25   12     8
# 7:    11   20   11    17
# 8:    11   20   12     1
# 9:    11   21   11     8
#10:    11   21   12   -13
#11:    11   25   11    -7
#12:    11   25   12    17
#13:    12   20   14    12
#14:    12   20   15    -7
#15:    12   21   14     3
#16:    12   21   15     9
#17:    12   25   14     6
#18:    12   25   15    -2

答案 1 :(得分:0)

根据我对问题的最新理解进行编辑 1-along是横断面ID 2-cros是给定样带上的采样点 所有年份都对所有样带进行了抽样,但并非每个样带上的所有采样点都在所有年份进行了抽样 4 - 问题是删除所有六年未采样的所有采样点

以下是删除这些行的方法:

require(plyr)
count_var<-ddply(dt, ~along+cros, summarise, count = length(year))
str(count_var)
dt<-merge(dt, count_var, by = c("along", "cros"), all.x = T)
dt_all6<-subset(dt, count==6)

使用所有年份的所有采样点制作dt:

along<-as.factor(rep(1:113, 54))
year<-as.factor(c(rep(1979, 1017), rep(1980, 1017), rep(1981, 1017), rep(1982, 1017), rep(1983, 1017), rep(1984, 1017)))
cros_A<-c(rep(5, 113), rep(10, 113), rep(15, 113), rep(20, 113), rep(25, 113), rep(30, 113), rep(35, 113), rep(40, 113), rep(45, 113))
cros<-as.factor(rep(cros_A, 6))
set.seed(2)
alti<-rnorm(6102, mean = 1.5, sd = 0.5)
dt<-cbind.data.frame(along, year, cros, alti)

现在删除一些采样点:

dt<-dt[c(1:100, 106:400, 406:1500, 1506:1600, 1606:2500, 2506:3000, 3006:3500, 3506:4000, 4006:5000, 5006:6102), ]