[英]Subset of a data frame with the penultimate values of one of the columns
我有一个data.frame,其中有很多列,其中一列具有示例区域的代码,另一列具有示例数。 我只想从每个样本区域中倒数第二个样本中提取信息。 我尝试了许多不同的方法……最后,这是我最好的猜测……但仍然无法正常工作。
site <- sample (1:3, 10, replace= T)
d2 <- sample (1:5, 10, replace= T)
d3 <- sample (1:5, 10, replace= T)
samplet <- sample (1:4, 10, replace= T)
mydata <- data.frame (cbind(site, d2, d3, samplet))
penultimate <- matrix(NA,,) # here I dont know how the return will be, as I dont know how the dataframe will change
si <- matrix (NA, , )
pl <- unique (site)
for (i in 1:(length (pl))) {
si <- mydata[which (samplet==pl[i]),] # I tried to create a temporary matrix, so I can calculate each site at a time
penultimate <- si[which (si$samplet!=(max(si$samplet[si$samplet!=max(si$samplet)]))),]
}
干杯!
一种简单的方法是使用data.table
及其内置的.N
值
# assuming `d1` is the column from which you want to find the penultimate
mydata <- data.frame(d1=strsplit("AAABBCCCCCDD", "")[[1]], d2=rnorm(12), d3=LETTERS[1:12], d4=c(101:103, 201:202, 301:305, 401:402))
DT <- data.table(mydata)
DT[, .SD[.N-1], by=d1]
d1 d2 d3 d4
1: A 1.6906714 B 102
2: B -0.1239458 D 201
3: C -0.2976339 I 304
4: D 0.6858120 K 401
> mydata
d1 d2 d3 d4
1 A 0.5986002 A 101
2 A 1.6906714 B 102 <~~~~ \
3 A -0.3253657 C 103
4 B -0.1239458 D 201 <~~~~ -\
5 B 0.8261401 E 202
6 C 0.0601318 F 301 Penultimate Values by d1
7 C -0.9766622 G 302
8 C 0.1028259 H 303
9 C -0.2976339 I 304 <~~~~~ -/
10 C -1.1467000 J 305
11 D 0.6858120 K 401 <~~~~~ /
12 D -0.6160335 L 402
编辑,并使用新的示例数据进行更新。
这是使用tapply
的数据使用tapply
的解决方案:
# data (thanks @Ricardo)
set.seed(1234)
mydata <- data.frame(d1=strsplit("AAABBCCCCCDD", "")[[1]],
d2=rnorm(12), d3=LETTERS[1:12],
d4=c(101:103, 201:202, 301:305, 401:402))
# solution
idx <- unlist(tapply(seq_len(nrow(mydata)), mydata$d1, function(x) x[length(x)-1]))
mydata[idx, ]
# d1 d2 d3 d4
# 2 A 0.2774292 B 102
# 4 B -2.3456977 D 201
# 9 C -0.5644520 I 304
# 11 D -0.4771927 K 401
如果id1
的特定值只有1行,则需要unlist
。
我将通过破坏功能尽我所能。 寻找在线路idx <- ...
,函数tapply
拆分序列c(1, 2, ... nrow(mydata))
这里, nrow(mydata) = 12
由列) mydata$d1
。 那是:
tapply(1:12, mydata$d1, c) # just to show what happens here
$A
[1] 1 2 3
$B
[1] 4 5
$C
[1] 6 7 8 9 10
$D
[1] 11 12
现在,代替功能c
我们需要每个元素中的最后一个元素。 因此,我们创建了一个function(x) x[length(x)-1]
,其中每个A, B, C, D
都一个接一个地传递,而代码x[length(x)-1]
选择了最后一个-但 每次 只有一个元素。 这些给您所有倒数第二行的行索引 。 因此,只需通过mydata[idx, ]
子集化data.frame即可。
除了先前的答案,还可以使用dplyr
进行此dplyr
:
set.seed(1234)
mydata <- data.frame(d1=strsplit("AAABBCCCCCDD", "")[[1]],
d2=rnorm(12), d3=LETTERS[1:12],
d4=c(101:103, 201:202, 301:305, 401:402))
require(dplyr)
mydata %.%
group_by(d1) %.%
mutate(count = 1:n()) %.%
filter(count %in% max(c(count-1,1))) %.%
select(-count)
就像在@BondedDust的答案中一样,如果任何给定的d1“组”只有一行,则我假设您使用单独的行
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.