将数据框减少到更少的行

时间:2015-03-27 00:02:32

标签: r dataframe reshape2

我们说我有一个数据框" dat"像:

 col1     col2
  12       a
  43       a
  54       a
  11       a
  33       b
  43       b
  34       c
  34       c
  342      c
  343      c

现在我有一个矢量

vec <- c(a,a,a,b,c,c)

我想要做的是删除数据框中的额外行&#34; dat&#34;按照矢量&#34; vec&#34;这意味着在数据框中只保留对应于&#34; a&#34;的前3 行,只保留对应于&#34; b&#34的前1 行;并且仅保留与<。

对应的前2

我应该输出

 col1     col2
  12       a
  43       a
  54       a
  33       b
  34       c
  34       c

无需使用for循环,最快的方法是什么?

4 个答案:

答案 0 :(得分:3)

这是一种使用splitMap的方式:

数据

dat <- read.table(header=T, text=' col1     col2
  12       a
  43       a
  54       a
  11       a
  33       b
  43       b
  34       c
  34       c
  342      c
  343      c',stringsAsFactors=F)

vec <-  c('a','a','a','b','c','c')

<强>解决方案

#count frequencies
tabvec <- table(vec)

data.frame(do.call(rbind,
   #use split to split data.frame according to col2
   #use head to only choose the first n rows according to tabvec
   #convert output into a data.frame
   Map(function(x,y) head(x,y),  split(dat, as.factor(dat$col2)), tabvec)
))

<强>输出:

    col1 col2
a.1   12    a
a.2   43    a
a.3   54    a
b     33    b
c.7   34    c
c.8   34    c

答案 1 :(得分:3)

使用dplyr即可:

#create a data frame with frequencies
tv <- data.frame(table(vec))

#filter values       
group_by(dat, col2) %>%
filter(row_number() <= tv$Freq[tv$vec %in% col2])

给出了:

#Source: local data frame [6 x 2]
#Groups: col2
#
#  col1 col2
#1   12    a
#2   43    a
#3   54    a
#4   33    b
#5   34    c
#6   34    c

答案 2 :(得分:3)

这是另一种Map()方法。

fvec <- factor(vec)
## find the index for the first occurrence of a new level
m <- match(levels(fvec), df$col2)

df[unlist(Map(seq, from = m, length.out = tabulate(fvec))), ]
#   col1 col2
# 1   12    a
# 2   43    a
# 3   54    a
# 5   33    b
# 7   34    c
# 8   34    c

或者您可以在匹配后使用rle()

rl <- rle(match(vec, df$col2))
df[unlist(Map(seq, rl$values, length.out = rl$lengths)),]
#   col1 col2
# 1   12    a
# 2   43    a
# 3   54    a
# 5   33    b
# 7   34    c
# 8   34    c

答案 3 :(得分:3)

这也可以在创建序列列之后完成

library(data.table)
setkey(setDT(dat)[, N:= 1:.N, col2], col2, N)
dat[setDT(list(col2=vec))[, N:=1:.N, col2]][, N:= NULL][]
#   col1 col2
#1:   12    a
#2:   43    a
#3:   54    a
#4:   33    b
#5:   34    c
#6:   34    c