【问题标题】:Avoid run time in looping避免循环中的运行时间
【发布时间】:2016-01-19 11:45:03
【问题描述】:

Test 是我想要提取值的数据库,即 emp id 向量,我还有一个名为 User 的文件,我想从中提取值。

测试数据库

命名员工 ID
一个

C
D
一个

用户文件

命名员工 ID
1
乙2
C 3
D 4
一个 1

我的循环中有两个条件。我找到匹配的值然后只有我选择它,如果有重复我只选择一个。我使用了这个循环。需要3个小时。我的用户文件中有数据框和 300000+ 行,我希望从中获取值。

for (i in 1:nrow(Test))
{`enter code here`
if(Test[i,"Name"] %in% User_Name)
{
item_id_found<-Test[i,"Name"]Test[i,"Emp_ID"]<-as.numeric(User[which(User$Name==item_id_found),"Emp_ID"])[1]}}

我需要知道一个更短的方法,比如应用函数。我想要数据框中的结果,而不是矩阵或列表。

【问题讨论】:

    标签: r loops apply


    【解决方案1】:

    如果我正确理解您的问题,您可以简单地合并这两个数据集。但是,在合并之前,我们 1) 从 test 中删除 Emp_ID 变量,以及 2) 删除 user。此方法假定Emp_ID 对于具有相同Name 的所有行都是相同的。

    x <- merge(test[, 1], user[!duplicated(user$Name), ], by = "Name")
    x
      Name Emp_Id
    1    A      1
    2    B      2
    3    C      3
    4    D      4
    

    更新

    根据 cmets 中的信息,我们需要考虑 a) test$Name 中的值在 user$Name 中不存在,以及 b) 从 user 中删除我们不想要的变量。这仍然可以通过merge 完成,我们只需要添加一些新选项即可。

    test <- data.frame(Name = c(LETTERS[1:6], "A", "E"), Emp_ID = NA, stringsAsFactors = FALSE)
    user <- data.frame(Name = c(LETTERS[1:4], "A"), Emp_ID = c(1:4, 1))
    x <- merge(subset(test, select = -c(Emp_ID)), user[!duplicated(user$Name), c("Name", "Emp_ID")], by = "Name", all.x = TRUE)
    x
    #   Name Emp_ID
    # 1    A      1
    # 2    A      1
    # 3    B      2
    # 4    C      3
    # 5    D      4
    # 6    E     NA
    # 7    E     NA
    # 8    F     NA
    

    我们使用subset 删除test 中的Emp_ID 变量,因为我们将要合并它。我们使用!duplicateduser 进行去重,然后明确声明只保留NameEmp_ID。最后,我们将all.x = TRUE 传递给merge 函数,以确保test 中没有在user 中找到的任何值都不会被删除。

    为了解决最后一个问题,即如果testuser 不共享Name 的相同变量,则合并,我们只需稍微调整merge 函数。

    names(user) <- c("Emp_Name", "Emp_ID")
    x <- merge(subset(test, select = -c(Emp_ID)), user[!duplicated(user$Emp_Name), c("Emp_Name", "Emp_ID")], by.x = "Name", by.y = "Emp_Name", all.x = TRUE)
    x
    #   Name Emp_ID
    # 1    A      1
    # 2    A      1
    # 3    B      2
    # 4    C      3
    # 5    D      4
    # 6    E     NA
    # 7    E     NA
    # 8    F     NA
    

    【讨论】:

    • 我认为这不是我想要的。假设测试有另一个元素 E 并且状态没有该元素,那么它不会返回 NA,而是在测试中返回 D。另外,如果假设用户有一个我不想与测试合并的列。我如何在这个函数本身中删除。
    • 什么是状态?这是test 中的变量吗?那是您所称的user 的实际名称吗?如果您只想要来自userEmp_ID,那么只需在合并语句中声明即可。 x &lt;- merge(test[, 1], user[! duplicated(user$name), "Emp_ID"], by = "Name").
    • 让我们说如果测试有另一个元素 E 并且用户没有那个元素那么它不会返回 NA 而是在测试中它返回 D。另外如果让我们说用户有一个我不想要的列与测试合并。如何在此功能本身中删除。在您的上述函数中,如果假设用户和测试对同一向量具有不同的标签。就像在用户中它是名称一样,在测试中它是名称,所以您发布的这个函数将起作用,或者我将不得不使用 by.x=name 和 by.y=Name 合并它
    • 我将编辑我的答案以适应新的条件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-06
    • 2012-10-08
    • 2011-03-20
    • 2014-01-24
    • 2014-04-13
    相关资源
    最近更新 更多