在因子后复制行值

时间:2014-05-09 23:58:10

标签: r data.table

给出以下数据框:

df <- data.frame(patientID = rep(c(1:4), 3), 
                 condition = c(rep("A", 4), rep("B",4), rep("C",4)),
                 weight = round(rnorm(12, 70, 7), 1),
                 height = round(c(rnorm(4, 170, 10), rep(0, 8)), 1))

> head(df)
  patientID condition weight height
1         1         A  71.43  168.5
2         2         A  59.89  177.3
3         3         A  72.15  163.4
4         4         A  70.14  166.1
5         1         B  66.21    0.0
6         2         B  66.62    0.0

如何将每个患者的身高从条件A复制到另外两个条件?我尝试使用for循环,data.table和dplyr但没有成功。

如何使用这两种方法实现这一目标?

3 个答案:

答案 0 :(得分:2)

如果您的数据看起来如此 - 按condition, patientID排序,并且每个条件的患者相同,那么您可以按照以下方式使用回收

require(data.table)
setDT(df)[, height := height[condition == "A"]]

但我明白那里有很多 ifs


因此,在没有假设数据的情况下,condition,patientID对是唯一的一个例外,您可以这样做:

require(data.table)
setDT(df)[, height := height[condition == "A"], by=patientID]

再次,这使用回收,但在每个组内 - 因为它不假设数据是有序的。


以上两种方法对样本数据给出:

#     patientID condition weight height
# 1:          1         A   73.3  169.5
# 2:          2         A   76.3  173.4
# 3:          3         A   63.6  145.5
# 4:          4         A   56.2  164.7
# 5:          1         B   67.7  169.5
# 6:          2         B   77.3  173.4
# 7:          3         B   76.8  145.5
# 8:          4         B   70.9  164.7
# 9:          1         C   76.6  169.5
# 10:         2         C   73.0  173.4
# 11:         3         C   66.7  145.5
# 12:         4         C   71.6  164.7

同样的想法也可以翻译为dplyr,我会留给你试试。提示:它只需要group_bymutate

答案 1 :(得分:1)

这里不需要花哨的东西。只需使用$运算符和[子集。

> df$height <- df$height[df$patientID]
> df
   patientID condition weight height
1          1         A   67.4  175.1
2          2         A   66.8  179.0
3          3         A   49.7  159.7
4          4         A   64.5  165.3
5          1         B   66.0  175.1
6          2         B   70.8  179.0
7          3         B   58.7  159.7
8          4         B   74.3  165.3
9          1         C   70.9  175.1
10         2         C   75.6  179.0
11         3         C   61.3  159.7
12         4         C   74.5  165.3

答案 2 :(得分:1)

这应该可以解决问题。它假设条件因子的第一级始终是具有真实数据的级别。

idx <- tapply(rownames(df), list(df$patientID, df$condition), identity)
idx<-na.omit(cbind(as.vector(idx[,-1]),as.vector(idx[,1])))
df[as.vector(idx[,1]),"height"] <- df[as.vector(idx[,2]), "height"]

来自@ Arun的建议

df$height<-with(df, ave(ifelse(condition=="A",height,-1), 
    factor(patientID), FUN=max))

您可以明确指出从

中提取值的条件级别