我试图回答我的问题,但我找不到;如果已有答案,请写下链接。
我有一个大约有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观测值。
谢谢
答案 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,]