重复行的功能

时间:2016-04-26 00:12:34

标签: r

我有一个如下数据框:

> df
     pat_id disease
[1,] "pat1" "dis1" 
[2,] "pat1" "dis1" 
[3,] "pat2" "dis0" 
[4,] "pat2" "dis5" 
[5,] "pat3" "dis2" 
[6,] "pat3" "dis2" 

如何编写一个函数来获取第三个变量,该变量指示同一个pat_id,疾病变量是否相同,如下所示?

> df
     pat_id disease var3
[1,] "pat1" "dis1"  "1" 
[2,] "pat1" "dis1"  "1" 
[3,] "pat2" "dis0"  "0" 
[4,] "pat2" "dis5"  "0" 
[5,] "pat3" "dis2"  "1" 
[6,] "pat3" "dis2"  "1" 

3 个答案:

答案 0 :(得分:5)

尝试any(duplicated())进行分组,并使用as.integer()cbind()的结果换行。然后与cbind( df, var3 = ave(df[,2], df[,1], FUN = function(x) as.integer(any(duplicated(x))) ) # pat_id disease var3 # [1,] "pat1" "dis1" "1" # [2,] "pat1" "dis1" "1" # [3,] "pat2" "dis0" "0" # [4,] "pat2" "dis5" "0" # [5,] "pat3" "dis2" "1" # [6,] "pat3" "dis2" "1" 绑定。虽然我可能会建议你在这里使用数据框而不是矩阵。

library(data.table)
dt <- as.data.table(df)
dt[, var3 := if(any(duplicated(disease))) 1 else 0, by = pat_id]

对于较大的数据,我建议转换为数据表。语法实际上也更好一些,而且可能会更快。

   pat_id disease var3
1:   pat1    dis1    1
2:   pat1    dis1    1
3:   pat2    dis0    0
4:   pat2    dis5    0
5:   pat3    dis2    1
6:   pat3    dis2    1

给出了

as.integer(any(duplicated(disease)))

其中列类更合适(char,char,int)。或者您可以使用if代替else / {{1}}。

答案 1 :(得分:0)

稍微啰嗦,但是给你一个布尔第三个变量,它更容易测试。它也不关心数据类型

> df <- data.frame(pat_id=c("pat1","pat1", "pat2", "pat2", "pat3", "pat3"), 
+                  disease=c("dis1","dis1","dis0","dis5","dis2","dis2"), 
+                  stringsAsFactors = F)
> counts<-apply(table(df), 1, function(x) sum(x!=0))
> df2<-data.frame(pat_id=names(counts), all_the_same=(counts==1))
> df3<-merge(df,df2)
> df3
  pat_id disease all_the_same
1   pat1    dis1         TRUE
2   pat1    dis1         TRUE
3   pat2    dis0        FALSE
4   pat2    dis5        FALSE
5   pat3    dis2         TRUE
6   pat3    dis2         TRUE
> sapply(df3, class)
      pat_id      disease all_the_same 
 "character"  "character"    "logical" 

这并不关心你拥有的每种组合中有多少,应该把你的字符串留作字符串 - 而不是因素。

将新列作为逻辑使您可以更轻松地进行查询,例如查找所有患者的查询

> unique(df3$pat_id[df3$all_the_same])
[1] "pat1" "pat3"

答案 2 :(得分:0)

使用dplyr

的一个选项
library(dplyr)
as.data.frame(df) %>%
     group_by(pat_id) %>%
     mutate(var3 = as.integer(n_distinct(disease)==1))
#  pat_id disease  var3
#   (chr)   (chr) (int)
#1   pat1    dis1     1
#2   pat1    dis1     1
#3   pat2    dis0     0
#4   pat2    dis5     0
#5   pat3    dis2     1
#6   pat3    dis2     1