计算R中数据框中具有条件的条目数(通用)

时间:2019-06-07 17:15:54

标签: r dataframe subset

我有一个包含数千个条目的数据框。我不知道列的名称和数量。我如何计算除最后一列外所有列中具有完全相同值的元素的数量

通常我会这样做:

nrow(subset(df, attr1 == value1 & attr2 == value2 & attr3 == value3))

但是在这种情况下,在运行此代码之前,我不知道有多少个属性。

考虑一下,我将所有请求的值(value1value2 ...)存储在x变量中,其构建方式如下:

 x = df[i,]

我尝试过

nrow(subset(df, colnames(df)[1:(ncol(df) - 1)] == x[1:(ncol(df) - 1)]))

但这会产生0

我在数据集上添加了一些信息作为参考。运行此代码:

print(x)
print(colnames(df))
print(head(df))

我获得以下输出:

377   3rd Male Adult       No
[1] "Class"    "Sex"      "Age"      "Survived"
  Class  Sex   Age Survived
1   3rd Male Child       No
3   3rd Male Child       No
4   3rd Male Child       No
5   3rd Male Child       No
6   3rd Male Child       No
7   3rd Male Child       No

2 个答案:

答案 0 :(得分:0)

这应该可以解决问题。

library(dplyr) ## for %>%
allDuplicated <- function(data){
  tmp <- data[,-ncol(data)]
  n <- ncol(tmp)
  apply(tmp, 1,function(x){ sum(x == x[1]) == n}) %>% unlist(.)
}

matrix <- matrix(c(rep(1,3),c(0,1,2)),2,3)
allDuplicated(mat)

您想知道所有功能是否都正确吗?因此,首先我们创建tmp数据集,在该数据集上您想知道没有差异的行。因此,如果所有值都与第一个相同,则应将其消除。然后,我们将其应用于数据集,检查是否所有x(现在是tmp中的行)的所有值都等于第一个值,如果有,则返回TRUE。所以现在您有了我假设要删除的行的索引。

答案 1 :(得分:0)

以下功能可完成问题的要求。
首先,它删除x的最后一个元素和DF的最后一列。
然后,Reduce将函数'=='应用于新x和新DF的每一行的列表。

countEqual <- function(DF, X){
  X <- X[-length(X)]
  DF <- DF[-ncol(DF)]
  eq <- apply(DF, 1, function(y){
    all(Reduce('==', list(X, y)))
  })
  sum(eq)
}

x <- c("3rd", "Male", "Adult", "No")

countEqual(df, x)
#[1] 0

countEqual(df, c("3rd", "Male", "Child", "No"))
#[1] 6

测试数据创建代码。

这是问题中的数据集,另外还有20行。

df <- read.table(text = "
  Class  Sex   Age Survived
1   3rd Male Child       No
3   3rd Male Child       No
4   3rd Male Child       No
5   3rd Male Child       No
6   3rd Male Child       No
7   3rd Male Child       No                 
", header = TRUE, stringsAsFactors = FALSE)

set.seed(1234)
n <- 20
Class <- sample(c("1st", "2nd", "4th"), n, TRUE)
Sex <- sample(c("Male", "Female"), n, TRUE)
Age <- sample(c("Child", "Adult"), n, TRUE)
Survived <- sample(c("Yes", "No"), n, TRUE)
df2 <- data.frame(Class, Sex, Age, Survived)

df <- rbind(df, df2)
df <- df[with(df, order(Class, Sex, Age, Survived)), ]
row.names(df) <- NULL