创建一个通用命令,用数千个观测值选择数据框中的某些观测值

时间:2016-09-12 06:48:33

标签: r

我试图回答我的问题,但我找不到;如果已有答案,请写下链接。

我有一个大约有50k观测数据的数据框;数据框包含2008年至2014年的观测资料,并且来自全国调查。每年都有一些家庭接受了采访,其他人则是新的。 我需要过滤数据框,以消除只出现一次的系列。 例如:

df[1:7,]

      NQUEST NORD ANNO
1      173    1   2008
2      375    1   2008
3      465    1   2008
4      465    2   2008
5      465    3   2008
6      465    4   2008
7      629    1   2008

s[13703:13710,]

      NQUEST NORD ANNO
82137    173    1 2010
82138    375    1 2010
82139    465    1 2010
82140    465    2 2010
82141    465    3 2010
82142    465    4 2010
82143    732    1 2010
82144    732    2 2010

Nquest是家庭的数量,而nord是家庭的组成部分。在这种情况下,我想消除家庭号码629和732。

如果观察出现多次,我尝试创建一个等于1的假人,否则为零,但问题是为每个观察创建一个通用命令(不写数字173等等,记住数据框包含50k观测值。

谢谢

4 个答案:

答案 0 :(得分:2)

我猜不是最有效的,但这是一种了解你不想要的家庭的方法:

names(which(rowSums(table(df$NQUEST, df$ANNO)!=0)==1))
#[1] "629" "732"

说明:
table允许根据NQUEST获取ANNO,然后您过滤掉仅在一年内出现的系列,并获取其姓名。

数据

df <- structure(list(NQUEST = c(173L, 375L, 465L, 465L, 465L, 465L, 
629L, 173L, 375L, 465L, 465L, 465L, 465L, 732L, 732L), NORD = c(1L, 
1L, 1L, 2L, 3L, 4L, 1L, 1L, 1L, 1L, 2L, 3L, 4L, 1L, 2L), ANNO = c(2008L, 
2008L, 2008L, 2008L, 2008L, 2008L, 2008L, 2010L, 2010L, 2010L, 
2010L, 2010L, 2010L, 2010L, 2010L)), .Names = c("NQUEST", "NORD", 
"ANNO"), class = "data.frame", row.names = c("1", "2", "3", "4", 
"5", "6", "7", "82137", "82138", "82139", "82140", "82141", "82142", 
"82143", "82144"))

NB:如果您有两个data.frames,则只需检查第二个data.frame(最近的条目)中的哪个不在第一个data.frame:which(!s$NQUEST %in% unique(df$NQUEST))中。 ..

答案 1 :(得分:1)

在plyr包中使用count函数

   library(plyr)

    tmp <- as.data.frame(count(df,vars = c("NQUEST","NORD")))
    tmp <- tmp[tmp$freq > 1,]
plyr中的

计数功能为您提供所有对的n路频率。因此,您可以使用多个频率过滤这些项目。

输出

   NQUEST NORD freq
1    173    1    2
2    375    1    2
3    465    1    2
4    465    2    2
5    465    3    2
6    465    4    2

答案 2 :(得分:1)

我有一个dplyr的解决方案。我把过滤放到一个函数中。您可以将多个数据帧作为参数放入函数中,它将转换为单个数据帧然后进行过滤。解释在代码中。我希望这有帮助。 (我还提供了一个包含更多行的示例)。

# Create function to filter
# you can provide several dataframes (with same columns) to the ... argument
filt_nqest <- function(...){

  library(dplyr)

  # put dataframes into a list of dataframes
  list_df <- list(...)

  # bind the dataframes together to one dataframe
  df <- bind_rows(list_df)

  df %>%
    select(NQEST,ANNO) %>% # selecting the two columns from the dataframe
    unique(.) %>% # reduces the dataframe to the unique combinations of family number and year
    count(NQEST) %>% # count the number of years, families were questioned
    filter(n > 1) -> famques # filter out families that were qestioned only once

  df %>% 
    filter(NQEST %in% famques$NQEST) -> df_filtered # use new variable to filter

  # return filtered dataframe
  return(df_filtered)

} # End of function  


# Create test data
NQEST <- c(173,375,465,465,465,465,732,732)
NORD <- c(1,1,1,2,3,4,1,2)
ANNO <- c(rep(2010,times=8))

s <- cbind.data.frame(NQEST,NORD,ANNO,stringsAsFactors=FALSE)

NQEST <- c(173,375,465,465,465,465,629)
NORD <- c(1,1,1,2,3,4,1)
ANNO <- c(rep(2008,times=7))

df <- cbind.data.frame(NQEST,NORD,ANNO,stringsAsFactors=FALSE)

# TEST with small example
filt_nqest(df,s) -> df_test


# test data from the dplyr package for use as a big example
require(Lahman)
df <- as.data.frame(Batting[1:100000,],stringsAsFactors=FALSE)
df %>% rename(NQEST=playerID, ANNO=yearID) -> df

s <- as.data.frame(Batting[100001:200000,],stringsAsFactors=FALSE)
s %>% rename(NQEST=playerID, ANNO=yearID) -> s

df_test <- filt_nqest(df,s)

答案 3 :(得分:-1)

这不应该是简单的交叉(唯一(df $ NQUEST),唯一(s $ NQUEST))给你两个共同的NQUEST,你想过滤掉只出现在其中一个中的那些。 / p>

common.NQUEST <- intersect(unique(df$NQUEST), unique(s$NQUEST))
df.filtered <- df[df$NQUEST %in% common.NQUEST,]
s.filtered <- s[s$NQUEST %in% common.NQUEST,]