具有多个条件的行和
rowsums with multiple conditions
我正在尝试计算具有多个变量的行中的累计总和。
这是我的数据示例。我有 5 个患者 ID 和 4 个条件变量。如果conditions中有'1 to 3'之间的值,cumsum会加1.
ID<-c("a","b","c","d","e")
cond1<-as.factor(sample(x=1:7,size=5,replace=TRUE))
cond2<-as.factor(sample(x=1:7,size=5,replace=TRUE))
cond3<-as.factor(sample(x=1:7,size=5,replace=TRUE))
cond4<-as.factor(sample(x=1:7,size=5,replace=TRUE))
df<-data.frame(ID,cond1,cond2,cond3,cond4)
df
ID cond1 cond2 cond3 cond4
1 a 2 7 6 6
2 b 7 2 3 6
3 c 4 3 1 4
4 d 7 3 3 6
5 e 6 7 7 3
我将 rowSums
代码与以下语句一起使用。但是,作为第 2 行,虽然 cond2
是 2,cond3
是 3,但 cumsum
不是 '2','1'。第 4 行有同样的问题。
df$cumsum<-rowSums(df[,2:5]==c(1,2,3),na.rm=TRUE)
df
ID cond1 cond2 cond3 cond4 cumsum
1 a 2 7 6 6 0
2 b 7 2 3 6 1
3 c 4 3 1 4 1
4 d 7 3 3 6 1
5 e 6 7 7 3 0
如何累积?非常感谢您的帮助。
要比较 1 个以上的元素,请使用 %in%
,但 %in%
适用于 vector
。因此,我们使用 lapply/sapply
遍历列,然后在逻辑矩阵
上执行 rowSums
df$RSum <- rowSums(sapply(df[,2:5], `%in%`, 1:3))
df$RSum
#[1] 1 2 2 2 1
如果值是数字,那么我们也可以使用 >
或 <
df$RSum <- rowSums(df[, 2:5] >=1 & df[, 2:5] <=3)
数据
df <- structure(list(ID = c("a", "b", "c", "d", "e"), cond1 = c(2L,
7L, 4L, 7L, 6L), cond2 = c(7L, 2L, 3L, 3L, 7L), cond3 = c(6L,
3L, 1L, 3L, 7L), cond4 = c(6L, 6L, 4L, 6L, 3L)),
class = "data.frame", row.names = c("1",
"2", "3", "4", "5"))
我建议您解决两个数据问题:
- 您的数据是宽格式的,而不是长格式的。如果你的数据是长格式的,你的分析会简单得多。对于绘图来说尤其如此。
- 您对每个条件的值都是因素。这使得进行比较变得更加困难,并且可能会导致一些 difficult-to-spot 错误。如果你看到@ak运行 仔细回答,你会注意到这些值是整数(数字)。
也就是说,我提出一个 data.table
解决方案:
# 1. load libraries and make df a data.table:
library(data.table)
setDT(df)
# 2. make the wide table a long one
melt(df, id.vars = "ID")
# 3. with a long table, count the number of conditions that are in the 1:3 range for each ID. Notice I chained the first command with this second one:
melt(df, id.vars = "ID")[, sum(value %in% 1:3), by = ID]
产生结果:
ID V1
1: a 1
2: b 2
3: c 2
4: d 2
5: e 1
您只需要 运行 在 1 和 3 下执行命令(2 已链接到 3)。有关详细信息,请参阅 ?data.table
。
您可以在 wikipedia and in
中阅读有关宽与长的更多信息
我用的数据和@ak一样运行:
df <- structure(list(ID = c("a", "b", "c", "d", "e"),
cond1 = c(2L, 7L, 4L, 7L, 6L),
cond2 = c(7L, 2L, 3L, 3L, 7L),
cond3 = c(6L, 3L, 1L, 3L, 7L),
cond4 = c(6L, 6L, 4L, 6L, 3L)),
class = "data.frame",
row.names = c("1", "2", "3", "4", "5"))
我正在尝试计算具有多个变量的行中的累计总和。
这是我的数据示例。我有 5 个患者 ID 和 4 个条件变量。如果conditions中有'1 to 3'之间的值,cumsum会加1.
ID<-c("a","b","c","d","e")
cond1<-as.factor(sample(x=1:7,size=5,replace=TRUE))
cond2<-as.factor(sample(x=1:7,size=5,replace=TRUE))
cond3<-as.factor(sample(x=1:7,size=5,replace=TRUE))
cond4<-as.factor(sample(x=1:7,size=5,replace=TRUE))
df<-data.frame(ID,cond1,cond2,cond3,cond4)
df
ID cond1 cond2 cond3 cond4
1 a 2 7 6 6
2 b 7 2 3 6
3 c 4 3 1 4
4 d 7 3 3 6
5 e 6 7 7 3
我将 rowSums
代码与以下语句一起使用。但是,作为第 2 行,虽然 cond2
是 2,cond3
是 3,但 cumsum
不是 '2','1'。第 4 行有同样的问题。
df$cumsum<-rowSums(df[,2:5]==c(1,2,3),na.rm=TRUE)
df
ID cond1 cond2 cond3 cond4 cumsum
1 a 2 7 6 6 0
2 b 7 2 3 6 1
3 c 4 3 1 4 1
4 d 7 3 3 6 1
5 e 6 7 7 3 0
如何累积?非常感谢您的帮助。
要比较 1 个以上的元素,请使用 %in%
,但 %in%
适用于 vector
。因此,我们使用 lapply/sapply
遍历列,然后在逻辑矩阵
rowSums
df$RSum <- rowSums(sapply(df[,2:5], `%in%`, 1:3))
df$RSum
#[1] 1 2 2 2 1
如果值是数字,那么我们也可以使用 >
或 <
df$RSum <- rowSums(df[, 2:5] >=1 & df[, 2:5] <=3)
数据
df <- structure(list(ID = c("a", "b", "c", "d", "e"), cond1 = c(2L,
7L, 4L, 7L, 6L), cond2 = c(7L, 2L, 3L, 3L, 7L), cond3 = c(6L,
3L, 1L, 3L, 7L), cond4 = c(6L, 6L, 4L, 6L, 3L)),
class = "data.frame", row.names = c("1",
"2", "3", "4", "5"))
我建议您解决两个数据问题:
- 您的数据是宽格式的,而不是长格式的。如果你的数据是长格式的,你的分析会简单得多。对于绘图来说尤其如此。
- 您对每个条件的值都是因素。这使得进行比较变得更加困难,并且可能会导致一些 difficult-to-spot 错误。如果你看到@ak运行 仔细回答,你会注意到这些值是整数(数字)。
也就是说,我提出一个 data.table
解决方案:
# 1. load libraries and make df a data.table:
library(data.table)
setDT(df)
# 2. make the wide table a long one
melt(df, id.vars = "ID")
# 3. with a long table, count the number of conditions that are in the 1:3 range for each ID. Notice I chained the first command with this second one:
melt(df, id.vars = "ID")[, sum(value %in% 1:3), by = ID]
产生结果:
ID V1
1: a 1
2: b 2
3: c 2
4: d 2
5: e 1
您只需要 运行 在 1 和 3 下执行命令(2 已链接到 3)。有关详细信息,请参阅 ?data.table
。
您可以在 wikipedia and in
我用的数据和@ak一样运行:
df <- structure(list(ID = c("a", "b", "c", "d", "e"),
cond1 = c(2L, 7L, 4L, 7L, 6L),
cond2 = c(7L, 2L, 3L, 3L, 7L),
cond3 = c(6L, 3L, 1L, 3L, 7L),
cond4 = c(6L, 6L, 4L, 6L, 3L)),
class = "data.frame",
row.names = c("1", "2", "3", "4", "5"))