我有一个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
答案 0 :(得分:3)
我们可以逐行使用192.168.0.x
并找出apply
和friend
列中出现的普通朋友的数量
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
值并且我们想排除它们,我们可以使用NA
和is.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”分组,gather
与summarise
的{{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