比较多列并创建匹配计数

时间:2019-01-08 04:29:35

标签: r loops

我有一个ID数据集,用于答复者的朋友和欺凌者。

我想遍历每一行的所有友谊提名和所有霸王提名,并计算出两者提名的人数。任何帮助都会很棒!

有数据:

ID  friend_1  friend_2  friend_3  bully_1  bully_2
1          4        12         7       12       15
2          8         6         7       18       20
3          9        18         1        2        1
4         15         7         2        7       13 
5          1        17         9       17        1
6          9        19        20       14       12
7         19        12        20        9       12
8          7         1        16        2       15 
9          1        10        12        1        7
10         7        11         9       11        7

想要的数据:

ID  friend_1  friend_2  friend_3  bully_1  bully_2  num_both
1          4        12         7       12       15         1
2          8         6         7       18       20         0
3          9        18         1        2        1         1
4         15         7         2        7       13         1
5          1        17         9       17        1         2
6          9        19        20       14       12         0
7         19        12        20        9       12         1
8          7         1        16        2       15         0
9          1        10        12        1        7         1
10         7        11         9       11        7         2

4 个答案:

答案 0 :(得分:3)

我们可以逐行使用192.168.0.x并找出applyfriend列中出现的普通朋友的数量

bully

或者,如果您不是df$num_both <- apply(df, 1, function(x) length(intersect(x[grep("friend", names(df))], x[grep("bully", names(df))]))) # ID friend_1 friend_2 friend_3 bully_1 bully_2 num_both #1 1 4 12 7 12 15 1 #2 2 8 6 7 18 20 0 #3 3 9 18 1 2 1 1 #4 4 15 7 2 7 13 1 #5 5 1 17 9 17 1 2 #6 6 9 19 20 14 12 0 #7 7 19 12 20 9 12 1 #8 8 7 1 16 2 15 0 #9 9 1 10 12 1 7 1 #10 10 7 11 9 11 7 2 的忠实拥护者,则可以按照相同的逻辑使用apply

sapply

编辑

如果有一些friend_cols <- grep("friend", names(df)) bully_cols <- grep("bully", names(df)) sapply(seq_len(nrow(df)), function(i) length(intersect(df[i, friend_cols, drop = TRUE], df[i, bully_cols, drop = TRUE]))) #[1] 1 0 1 1 2 0 1 0 1 2 值并且我们想排除它们,我们可以使用NAis.na

sum

答案 1 :(得分:3)

假设值在朋友/欺凌者群体中是唯一的,那么一种简单的方法是:

apply(df[,-1], 1, function (x) sum(table(x) > 1)) 
[1] 1 0 1 1 2 0 1 0 1 2

答案 2 :(得分:1)

您可以尝试将每个bully列与friends列进行比较,然后采用并集来计算匹配矩阵。要获得num_both,您只需rowSum这个匹配矩阵:

bully_cols <- grep("bully", names(df))
friend_cols <- grep("friend", names(df))
df$num_both <- rowSums(Reduce("|", lapply(df[,bully_cols], function(x, compare) compare == x, compare = df[,friend_cols])))

lapply计算每个欺负者列的匹配项,然后Reduce将它们组合到一个矩阵中以求和。

#   ID friend_1 friend_2 friend_3 bully_1 bully_2 num_both
#1   1        4       12        7      12      15        1
#2   2        8        6        7      18      20        0
#3   3        9       18        1       2       1        1
#4   4       15        7        2       7      13        1
#5   5        1       17        9      17       1        2
#6   6        9       19       20      14      12        0
#7   7       19       12       20       9      12        1
#8   8        7        1       16       2      15        0
#9   9        1       10       12       1       7        1
#10 10        7       11        9      11       7        2

答案 3 :(得分:0)

这是melt中基于data.table的方法。根据列名中的melt patterns friend bully为{long}格式,以'ID'分组,得到{{1 }}个length中的长数据集列'value1','value2'的元素,并连接intersect'ID'

on

或者通过library(data.table) setDT(df1)[melt(df1, measure = patterns('^friend', '^bully'))[, .(num_both = length(intersect(value1, value2))), ID], on = .(ID)] # ID friend_1 friend_2 friend_3 bully_1 bully_2 num_both # 1: 1 4 12 7 12 15 1 # 2: 2 8 6 7 18 20 0 # 3: 3 9 18 1 2 1 1 # 4: 4 15 7 2 7 13 1 # 5: 5 1 17 9 17 1 2 # 6: 6 9 19 20 14 12 0 # 7: 7 19 12 20 9 12 1 # 8: 8 7 1 16 2 15 0 # 9: 9 1 10 12 1 7 1 #10: 10 7 11 9 11 7 2 使用tidyverse成“长”格式,按“ ID”分组,gathersummarise的{​​{1}} ing个元素基于在“键”列中出现“朋友”或“欺凌者”和使用原始数据集length而得出的“值”

intersect

或通过用right_join遍历行的另一种方法

library(tidyverse)
df1 %>% 
   gather(key, value, -ID) %>% 
   group_by(ID) %>% 
   summarise(num_both = length(intersect(value[str_detect(key, 'friend')], 
                         value[str_detect(key, 'bully')]))) %>% 
   right_join(df1)
# A tibble: 10 x 7
#      ID num_both friend_1 friend_2 friend_3 bully_1 bully_2
#   <int>    <int>    <int>    <int>    <int>   <int>   <int>
# 1     1        1        4       12        7      12      15
# 2     2        0        8        6        7      18      20
# 3     3        1        9       18        1       2       1
# 4     4        1       15        7        2       7      13
# 5     5        2        1       17        9      17       1
# 6     6        0        9       19       20      14      12
# 7     7        1       19       12       20       9      12
# 8     8        0        7        1       16       2      15
# 9     9        1        1       10       12       1       7
#10    10        2        7       11        9      11       7

数据

pmap