通过递增行数来计算类似对象

时间:2017-03-02 00:59:16

标签: r

我有两个数据框df1df2,如下所示。

df1 

    user
1    U1
2    U2
3    U3
4    U4
5    U5
6    U6
7    U7
8    U8
9    U9
10   U10



 df2
     user
1   U3
2   U4
3   U10

我想检查df2中有df1个用户的数量,当我将前两行放在一起时,前4行放在一起等等。

我期待的是;

 selected_users   matching_users
    2              0
    4              2
    6              2
    8              2 
   10              3

在我的实际数据中,df1有1000行,我可以一次增加50行。

我使用了一种繁琐的方式,使用head(df1,2),head(df1,4)等手动完成每一步。但我觉得应该有一个更容易的方法来做到这一点。

有人可以建议一种有效的方法吗。

3 个答案:

答案 0 :(得分:4)

不需要提供lapply,sapply或auxillary功能。

df1 = data.frame(user = c("U1", "U2", "U3", "U4", "U5",
    "U6", "U7", "U8", "U9", "U10"))
df2 = data.frame(user = c("U3", "U4", "U10"))
a=cumsum(df1$user %in% df2$user)
ind=seq(2,10,2)
cbind(ind,a[ind])

输出:

     ind  
[1,]   2 0
[2,]   4 2
[3,]   6 2
[4,]   8 2
[5,]  10 3

答案 1 :(得分:3)

此答案返回每个增量的匹配列表

df1 = data.frame(user = c("U1", "U2", "U3", "U4", "U5", "U6", "U7", "U8", "U9", "U10"))
df2 = data.frame(user = c("U3", "U4", "U10"))

count_incre = function(DF1, DF2, increments){
  return(DF2[DF2$user %in% head(DF1, increments)$user,])
}

lapply(seq(2, nrow(df1), 2), function(x) count_incre(df1, df2, x))

# [[1]]
# factor(0)
# Levels: U10 U3 U4
# 
# [[2]]
# [1] U3 U4
# Levels: U10 U3 U4
# 
# [[3]]
# [1] U3 U4
# Levels: U10 U3 U4
# 
# [[4]]
# [1] U3 U4
# Levels: U10 U3 U4
# 
# [[5]]
# [1] U3  U4  U10
# Levels: U10 U3 U4

我首先创建了一个函数count_incre,它使用df1df2head()的行数,并返回所有"用户"可以在DF2中找到head(DF1, increments)。然后使用increments将该函数应用于seq(2, nrow(df1), 2)的向量,我将其指定为lapply(基本上所有偶数)。您可以修改seq(2, nrow(df1), 2)以指定所需的任何序列。

仅计算匹配数

increments = seq(2, nrow(df1), 2)
matching_users = sapply(increments, function(x) length(count_incre(df1, df2, x)))

# [1] 0 2 2 2 3

data.frame(selected_users = increments, matching_users)

#   selected_users matching_users
# 1              2              0
# 2              4              2
# 3              6              2
# 4              8              2
# 5             10              3

为每个增量返回匹配数的向量

答案 2 :(得分:0)

df1 <- data.frame(user = paste0("U",seq(1,1000)))
df2 <- data.frame(user = paste0("U",sample(seq(1,2000),1000,replace = F)))
head(df1)
  user
1   U1
2   U2
3   U3
4   U4
5   U5
6   U6
head(df2)
   user
1  U537
2 U1133
3  U769
4  U217
5 U1924
6  U536

我使用 intersect 来计算匹配数。

find_match <- function (df1, df2, step){
  result <- data.frame(selected_users = rep(0, nrow(df1) / step),matching_users = rep(0, nrow(df1) / step))
  time <- 1
  increment_vec <- seq(step, nrow(df1), by=step)
  for(i in increment_vec){
    result[time,1] <- i
    result[time,2] <- length(intersect(unlist(df1), unlist(df2[1:i, 1])))
    time <- time + 1
  }
  return(result)
}
find_match(df1,df2,step=50)

结果是:

   selected_users matching_users
1              50             26
2             100             47
3             150             73
4             200             99
5             250            130
6             300            151
7             350            172
8             400            199
9             450            225
10            500            248
11            550            273
12            600            298
13            650            321
14            700            348
15            750            372
16            800            398
17            850            429
18            900            453
19            950            472
20           1000            499