我试图找到一种更 R 风格的方式来选择 R 中组的第二个元素(但不是第一个)。
我结束了: 1. 创建一个索引rowNumIndex;2. 选择并将前两行放入一个数据框中,然后将前两行放入单独的数据框中;然后 3. “反向合并” 2 个数据帧以仅从数据帧中获取前两行的唯一值:
firsts <- ddply(df,.(group), function(x) head(x,1)) # 2 records using data below
seconds <- ddply(df,.(group), function(x) head(x,2)) # 4 records using data below
real.seconds <- seconds[!seconds$rowNumIndex %in% firsts$rowNumIndex, ] # 2 records, the second elements only
Run Code Online (Sandbox Code Playgroud)
这是一些假装数据:
group var1 rowNumIndex
A 8 1
A 9 2
A 10 3
B 11 4
B 12 5
B 13 6
B 14 7
structure(list(group = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 2L
), .Label = c("A", "B"), class = "factor"), var1 = 8:14, rowNumIndex = 1:7), .Names = c("group",
"var1", "rowNumIndex"), class = "data.frame", row.names = c(NA,
-7L))
Run Code Online (Sandbox Code Playgroud)
所以,数据框firsts看起来像:
group var1 rowNumIndex
A 8 1
B 11 4
Run Code Online (Sandbox Code Playgroud)
和数据框seconds看起来像:
group var1 rowNumIndex
A 8 1
A 9 2
B 11 4
B 12 5
Run Code Online (Sandbox Code Playgroud)
和数据框real.seconds看起来像:
group var1 rowNumIndex
A 9 2
B 12 5
Run Code Online (Sandbox Code Playgroud)
有没有办法在不求助于索引的情况下做到这一点?提前感谢您提供的无疑是一个令人心碎的简单而优雅的解决方案!
一个解决方案dplyr:
library(dplyr)
group_by(df, group) %>% slice(2)
# group var1 rowNumIndex
# <fctr> <int> <int>
# 1 A 9 2
# 2 B 12 5
Run Code Online (Sandbox Code Playgroud)
预dplyr 0.3替代:
group_by(df, group)%.%filter(seq_along(var1)==2)
group var1 rowNumIndex
1 A 9 2
2 B 12 5
Run Code Online (Sandbox Code Playgroud)
此解决方案将保留数据的所有列。如果你只想要两列(group 和 var),你可以这样做:
group_by(df, group)%.%summarise(var1[2])
group var1[2]
1 A 9
2 B 12
Run Code Online (Sandbox Code Playgroud)
一个解决方案split,lapply和do.call
real.seconds<-do.call("rbind", lapply(split(df, df$group), function(x) x[2,]))
Run Code Online (Sandbox Code Playgroud)
这会给你:
real.seconds
group var1 rowNumIndex
A A 9 2
B B 12 5
Run Code Online (Sandbox Code Playgroud)
或者,更优雅地,使用by:
real.seconds <- do.call(rbind, by(df, df$group, function(x) x[2, ]))
Run Code Online (Sandbox Code Playgroud)