R:Vlookup进行“ for”循环

时间:2020-01-01 21:37:38

标签: r

我是R的新手,正在尝试使用它代替Excel(我有更多经验)。我仍在制定完整的“ for”逻辑,但没有值来确定它是否在起作用,我认为应该如何阻止我前进。目标是生成将被用作3个级别的因子; 0 =无重复,1为重复(最旧),2 =如果重复,最新。

我有一个看起来像这样的数据框

Person <- c("A", "B", "C", "C", "D", "E","E")
Date <- c(1/1/20, 1/1/20,12/25/19, 1/1/20, 1/1/20, 12/25/19, 1/1/20)
ID <- c(1,2,3,4,5,6,7)
DuplicateStatus <- c(0,0,0,0,0,0,0)
IdealResult <- c(0,0,1,2,0,1,2)
mydata <- cbind(Person, Date, ID, DuplicateStatus, IdealResult)

我正在尝试使用for循环来评估人员是否重复。如果某人不重复,则值= 0,并且如果确实重复,则他们的最旧值应为1,最新值应为2(请参见理想结果)。注意:我已经对数据进行了排序,然后按日期排序,因此,如果重复,则最早出现的时间是最早的。

以前在R答案中对Vlookup的研究旨在针对基于多个数据集中相同值的数据集进行合并。在这里,我试图基于单个数据集中的列之间的关系来修改列。

currentID = 0
  nextID =0

  for(i in mydata$ID){
    currentID = i 
    nextID = currentID++1

CurrentPerson ## Vlookup函数可以执行-在ID中找到currentID,并在同一位置的Person列中返回关联的值。

NextPerson ## Vlookup函数可以执行-在ID中找到nextID,并在同一位置的Person列中返回关联的值。

如果CurrentPerson = NextPerson,则与当前人员关联的ID处的DuplicateStatus应为1,而与NextPerson关联的ID处的DuplicateStatus应为2。

**这应该在当前人数=总人数时结束 谢谢!

4 个答案:

答案 0 :(得分:2)

您真的需要花费一些时间来学习有关R的简单教程。cbind()函数将所有数据转换为字符矩阵,而这可能不是您想要的。查看str(mydata)的结果。而不是循环,这将在每个Person组内创建一个索引号,然后通过一次观察将这些组清零:

mydata <- data.frame(Person, Date, ID, DuplicateStatus, IdealResult)
IR <- ave(mydata$ID, mydata$Person, FUN=seq_along)
IR
# [1] 1 1 1 2 1 1 2
tbl <- table(mydata$Person)
tozero <- mydata$Person %in% names(tbl[tbl == 1])
IR[tozero] <- 0
IR
# [1] 0 0 1 2 0 1 2

答案 1 :(得分:1)

您要查找的只是在一个列(例如列ID)中计算一个人的观察次数吗?如果是这样,可以使用tidyverse

Person <- c("A", "B", "C", "C", "D", "E","E")
Date <- c(1/1/20, 1/1/20,12/25/19, 1/1/20, 1/1/20, 12/25/19, 1/1/20)
ID <- c(1,2,3,4,5,6,7)
DuplicateStatus <- c(0,0,0,0,0,0,0)
IdealResult <- c(0,0,1,2,0,1,2)
mydata <- data.frame(Person, Date, ID, DuplicateStatus, IdealResult)

library(tidyverse)

mydata <- mydata %>%
    group_by(Person) %>%
    mutate(Duplicate = seq_along(Person))

mydata

# A tibble: 7 x 6
# Groups:   Person [5]
  Person   Date    ID DuplicateStatus IdealResult Duplicate
  <fct>   <dbl> <dbl>           <dbl>       <dbl>     <int>
1 A      0.05       1               0           0         1
2 B      0.05       2               0           0         1
3 C      0.0253     3               0           1         1
4 C      0.05       4               0           2         2
5 D      0.05       5               0           0         1
6 E      0.0253     6               0           1         1
7 E      0.05       7               0           2         2

答案 2 :(得分:0)

如果每个组中有多于一行,则可以在提供的每个组中分配行号。

这可以在基数R dplyrdata.table中实现

在基数R中:

mydata$ans <- with(mydata, ave(ID, Person, FUN = function(x) 
                           seq_along(x) * (length(x) > 1)))

#  Person      Date ID IdealResult ans
#1      A 0.0500000  1           0   0
#2      B 0.0500000  2           0   0
#3      C 0.0252632  3           1   1
#4      C 0.0500000  4           2   2
#5      D 0.0500000  5           0   0
#6      E 0.0252632  6           1   1
#7      E 0.0500000  7           2   2

使用dplyr

library(dplyr)
mydata %>% group_by(Person) %>% mutate(ans = row_number() * (n() > 1))

data.table

library(data.table)
setDT(mydata)[, ans := seq_along(ID) * (.N > 1), Person]

数据

mydata <- data.frame(Person, Date, ID, IdealResult)

答案 3 :(得分:-1)

我认为n()是解决您问题的理想函数

library(tidyverse)

mydata <- mydata %>%
  group_by(Person) %>%
  mutate(Duplicate = n())
相关问题