在R

时间:2015-09-14 13:19:37

标签: r dplyr

我正在使用一个数据集,其中包含一个包含电话号码的列,以及一个包含是或否的列。

  phone.number yes.no
1   7539339393      Y
2    111111111      N
3   1234567890      Y
4   7539339393      N
5   1222222222      Y
6   3333333333      N
7   4444444444      Y
8   5555555555      N
9   7539339393      Y
下面

dput

structure(list(phone.number = structure(c(7L, 1L, 3L, 7L, 2L, 
    4L, 5L, 6L, 7L), .Label = c("111111111", "1222222222", "1234567890", 
    "3333333333", "4444444444", "5555555555", "7539339393"), class = "factor"), 
        yes.no = structure(c(2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L), .Label = c("N", 
        "Y"), class = "factor")), .Names = c("phone.number", "yes.no"
    ), row.names = c(NA, -9L), class = "data.frame")

我非常欣赏一些帮助。

  1. 我正在尝试创建一个子集,其中包含已在数据集中重复3次或更多次的所有电话号码。因此,在提供的示例中,数字7539339393重复3次,我想做的子集将仅包括这些观察以及相应的是和否值。

  2. 我也尝试为所有返回yes和no的电话号码进行子集。因此,在提供的数据集中,7539339393对应于是和否,我想创建一个包含所有返回两者的电话号码的子集以及所有相应的是和否值

3 个答案:

答案 0 :(得分:3)

base R

1:

df[df$phone.number %in% names(which(table(df$phone.number) >= 3)),]
#  phone.number yes.no
#1   7539339393      Y
#4   7539339393      N
#9   7539339393      Y

我们根据出现3次或更多次的电话号码进行分组。 table计算向量中的所有元素。

2:

df[as.logical(ave(as.character(df$yes.no), df$phone.number, FUN= function(x) all(c("Y", "N") %in% x))),]
#  phone.number yes.no
#1   7539339393      Y
#4   7539339393      N
#9   7539339393      Y

dplyrdata.table中有很好的分组功能,这是一种基本的R方法,可以突出显示基本R的强度或其他包的优势,具体取决于你如何看待它。作为一个班轮,它有点冗长。从内到外,all用于检查是否出现。功能ave有助于通过唯一的电话号码完成操作。

答案 1 :(得分:1)

可能的dplyr方法..

1:

df %>% group_by(phone.number) %>% filter(n() >= 3)
#Source: local data frame [3 x 2]
#Groups: phone.number [1]
#
#  phone.number yes.no
#        (fctr) (fctr)
#1   7539339393      Y
#2   7539339393      N
#3   7539339393      Y

n()返回dplyr中每组的行数)

2:

df %>% group_by(phone.number) %>% filter(all(c("Y", "N") %in% yes.no))
#Source: local data frame [3 x 2]
#Groups: phone.number [1]
#
#  phone.number yes.no
#        (fctr) (fctr)
#1   7539339393      Y
#2   7539339393      N
#3   7539339393      Y

对于1. + 2.合并:

df %>% group_by(phone.number) %>% filter(n() >= 3 & all(c("Y", "N") %in% yes.no))
#Source: local data frame [3 x 2]
#Groups: phone.number [1]
#
#  phone.number yes.no
#        (fctr) (fctr)
#1   7539339393      Y
#2   7539339393      N
#3   7539339393      Y

答案 2 :(得分:0)

这是一个data.table解决方案,调用您的数据集df

library(data.table)
setDT(df)[,.SD[.N>2],by=phone.number]
#    phone.number yes.no
# 1:   7539339393      Y
# 2:   7539339393      N
# 3:   7539339393      Y

第二部分:

df[,.SD[length(unique(yes.no))>1], by=phone.number]

请注意,setDT(df)会将df转换为data.table,因此您无需在第二部分再次调用它。

这种方法可能比任何其他方法都快,但除非您的数据集非常大,否则您可能不会注意到差异。