我正在尝试重组一群人。
在数据中,“FamID”表示家庭,“PtID”表示与家庭有关的个体患者。 “Twin”栏表示患者是否是同卵双胞胎(编码为1),非同卵双胞胎(编码为2)或不是双胞胎(编码为0)。
FamID PtID Twin
F1 F11 1
F1 F12 1
F2 F21 2
F2 F22 2
F3 F31 1
F3 F32 1
F4 F41 2
F5 F51 1
F5 F52 1
F5 F53 0
F6 F61 1
F6 F62 1
F7 F71 2
F7 F72 2
例如,'FamID'F1有两个家庭成员,PtID F11和F12,他们是同卵双胞胎(Twin = 1)。
我想创建一个具有基于Twin列和FamID列的编码的列(NewCol)。
Twin列中的第一组同卵双胞胎(编码为1)在新列中将为1,而来自不同家族的第二组同卵双胞胎将为3,其中以下一组同卵双胞胎将为下一个奇数等等。
对于不同的双胞胎(编码为2s),它们将以偶数递增,第一个非同卵双胞胎从2开始上升。
任何非双胞胎(编码为0),它们将保持为0。
期望的输出:
FamID PtID Twin NewCol
F1 F11 1 1
F1 F12 1 1
F2 F21 2 2
F2 F22 2 2
F3 F31 1 3
F3 F32 1 3
F4 F41 2 4
F5 F51 1 5
F5 F52 1 5
F5 F53 0 0
F6 F61 1 7
F6 F62 1 7
F7 F71 2 6
F7 F72 2 6
数据
FamID <- c(rep("F1", 2), rep("F2", 2), rep("F3", 2), "F4", rep("F5", 3), rep("F6", 2), rep("F7", 2))
PtID <- c("F11", "F12", "F21", "F22", "F31", "F32", "F41", "F51", "F52", "F53", "F61", "F62", "F71", "F72")
Twin <- c(1, 1, 2, 2, 1, 1, 2, 1, 1, 0, 1, 1, 2, 2)
sample <- data.frame(FamID, PtID, Twin)
答案 0 :(得分:4)
以下是使用data.table
包的解决方案:
dt <- data.table(sample)
dt[Twin == 0, NewCol := 0L]
dt[Twin == 1, NewCol := .GRP * 2L - 1L, by = FamID]
dt[Twin == 2, NewCol := .GRP * 2L, by = FamID]
结果是
# FamID PtID Twin NewCol
# 1: F1 F11 1 1
# 2: F1 F12 1 1
# 3: F2 F21 2 2
# 4: F2 F22 2 2
# 5: F3 F31 1 3
# 6: F3 F32 1 3
# 7: F4 F41 2 4
# 8: F5 F51 1 5
# 9: F5 F52 1 5
# 10: F5 F53 0 0
# 11: F6 F61 1 7
# 12: F6 F62 1 7
# 13: F7 F71 2 6
# 14: F7 F72 2 6
Data.tables具有多种优点(直观的语法,许多操作中的效率),与大多数函数一起使用时,其行为与data.frames完全相同。但是,您可以使用
转换回data.framedf <- as.data.frame(dt)
答案 1 :(得分:4)
使用factor
和data.table
library(data.table)
DT.Sample <- data.table(sample)
DT.Sample[ , NewCol := 0]
DT.Sample[Twin==1 , NewCol:= 2*as.numeric(factor(FamID))-1]
DT.Sample[Twin==2 , NewCol:= 2*as.numeric(factor(FamID))]
FamID PtID Twin NewCol
1: F1 F11 1 1
2: F1 F12 1 1
3: F2 F21 2 2
4: F2 F22 2 2
5: F3 F31 1 3
6: F3 F32 1 3
7: F4 F41 2 4
8: F5 F51 1 5
9: F5 F52 1 5
10: F5 F53 0 0
11: F6 F61 1 7
12: F6 F62 1 7
13: F7 F71 2 6
14: F7 F72 2 6