在非常大的数据集中使用多个条件进行子集化

Subsetting with multiple conditions in very large data set

我有一个大约 430 X 20,000 的矩阵。每一行是一个人,每一列是他们从事的一个项目。每个单元格的值为 0 -(不参与)、1 -(项目负责人,每个项目只有一个)、2 -(项目助手)。我试图只看一个人负责的项目。我一次只想看一个人。因此,对于 A 人,我需要 r 删除该人的值不是 1 的所有列。但我想保留这些列中其他人的所有数据。

例如:

 Name   Project 1   Project 2......Project 2,000
Person A      1            0                    2
Person B      0            1                    1
Person C      2            2                    2

我正在尝试为 B 获取一些东西,以删除他们没有领导的专栏。

 Name    Project 2......   Project 2,000
Person A      0                    2
Person B      1                    1
Person C      2                    2

抱歉,如果这很明显,出于某种原因,我真的很难找到这么大数据的示例(a.k.a我不能只输入列名,因为太多了)。任何帮助将不胜感激。

所以您要做的只是 select 基于 行 [=41] 之一的值的数据框=].使用类似于您的示例的数据框:

> df
#      Name Project1 Project2 Project2000
#1 Person A        1        0           2
#2 Person B        0        1           1
#3 Person C        2        2           2

为了 select 列,例如 "Person B",您需要一个 逻辑向量 指示要保留的列,即向量,其长度与数据框中的列数相同,并且包含在结果中的列的值为 TRUE,否则为 FALSE

您可以几乎通过以下方式做到这一点:

> leadB <- df[2,]==1
#   Name Project1 Project2 Project2000
#2 FALSE    FALSE     TRUE        TRUE

它会挑选出正确的项目,但会删除 Name 列;为了也包含该列,我们使用:

> leadB <- c(TRUE, df[2,-1]==1)
#[1]  TRUE FALSE  TRUE  TRUE

然后将此向量用于数据帧中的 select 列:

> df_B <- df[,leadB]
#      Name Project2 Project2000
#1 Person A        0           2
#2 Person B        1           1
#3 Person C        2           2

当然,您可以在一行中执行此操作,并且 "Person B" 行没有什么特别之处,因此您可以使用一个函数,该函数 returns 中的人所需的数据框行 n:

leader_df <- function(n){
    df[,c(TRUE, df[n,-1]==1)]
}

然后对从 1 到行数的 n 的值计算 leader_df(n) 将为您提供每个项目负责人的数据框。

您可以通过首先搜索与所考虑的特定人员对应的行来轻松解决此问题。然后,您可以找到此人作为项目负责人的相关列,并从数据框中提取这些列(包括人员姓名)。下面是一个例子:

创建数据:

> person = c("John", "Willy", "Bob", "Anna", "Tom","Billy") 
> project1 = c(1, 0, 2, 0, 0,2) 
> project2 = c(1, 2, 0, 2, 0,0) 
> project3 = c(2, 0, 1, 0, 2,0)       # df is a data frame
> project4 = c(0, 0, 0, 1, 2,0)
> projects <- data.frame(person,project1,project2,project3,project4)

> projects
  person project1 project2 project3 project4
1   John        1        1        2        0
2  Willy        0        2        0        0
3    Bob        2        0        1        0
4   Anna        0        2        0        1
5    Tom        0        0        2        2
6  Billy        2        0        0        0

获取约翰的相关信息。请注意,我们需要明确添加具有人名的列:

> findPerson = "John"
> rowIndex <- which(projects$person==findPerson)
> columnIndex <- c(1,which(projects[rowIndex,]==1))
> if(length(columnIndex) > 1) # Only generate table if projectleader for at least one project
+   result <- projects[,columnIndex]

> result
  person project1 project2
1   John        1        1
2  Willy        0        2
3    Bob        2        0
4   Anna        0        2
5    Tom        0        0
6  Billy        2        0

假设您的数据名为 df,第一列是名称,所有其他列都是项目,这应该为一个人完成这项工作,例如"Person B":

df_B = df[, (df[2,] == 1)]

如果您需要更多人使用它,请按照 akrun 的建议将其放入一个循环中,并将您的输出存储在列表中。