根据R数据帧中的多个条件循环或申请行总和
Loop or apply for sum of rows based on multiple conditions in R dataframe
我已经找到了一个快速解决我的问题的方法,但我觉得它很迟钝。此外,它使用 for 循环,从我收集的信息来看,在 R 中应该不惜一切代价避免使用循环。感谢整理此代码的任何和所有建议。我对 R 还是很陌生,但我担心我把一个相对简单的问题搞得太复杂了。
我有一个数据集如下:
id count group
2 6 A
2 8 A
2 6 A
8 5 A
8 6 A
8 3 A
10 6 B
10 6 B
10 6 B
11 5 B
11 6 B
11 7 B
16 6 C
16 2 C
16 0 C
18 6 C
18 1 C
18 6 C
我想创建一个新的数据框,其中包含每个唯一 ID 的前两个计数的总和(例如,ID 2 为 6+8=14)。我还想附加正确的组标识符。
通常,当您连续几天测量不同受试者和治疗的值时,您可能需要这样做,并且您想要计算每个受试者在测量的前 x 天的总和。
这是我想出的:
id <- c(rep(c(2,8,10,11,16,18),each=3))
count <- c(6,8,6,5,6,3,6,6,6,5,6,7,6,2,0,6,1,6)
group <- c(rep(c("A","B","C"),each=6))
df <- data.frame(id,count,group)
newid<-c()
newcount<-c()
newgroup<-c()
for (i in 1:length(unique(df$"id"))) {
newid[i] <- unique(df$"id")[i]
newcount[i]<-sum(df[df$"id"==unique(df$"id")[i],2][1:2])
newgroup[i] <- as.character(df$"group"[df$"id"==newid[i]][1])
}
newdf<-data.frame(newid,newcount,newgroup)
一些可能improvements/alternatives我不确定:
- For 循环与应用函数
- 我可以直接在 for 循环内创建数据框,还是应该坚持创建可以稍后分配给数据框的向量?
- accessing/subsetting vectors/columns ($, [], [[]], subset?)
更一致的方法
聚合时可以尝试使用自定义函数
sum1sttwo<-function (x){
return(x[1]+x[2])
}
aggregate(count~id+group, data=df,sum1sttwo)
输出为:
id group count
1 2 A 14
2 8 A 11
3 10 B 12
4 11 B 11
5 16 C 8
6 18 C 7
04/2015 编辑:当您的数据集很大时,dplyr 和 data.table 绝对是更好的选择。 base R 最重要的缺点之一是数据帧太慢。但是,如果你只是需要聚合一个非常simple/small的数据集,base R中的聚合函数就可以达到目的。
library(plyr)
-Keep first 2 rows for each group and id
df2 <- ddply(df, c("id","group"), function (x) x$count[1:2])
-Aggregate by group and id
df3 <- ddply(df2, c("id", "group"), summarize, count=V1+V2)
df3
id group count
1 2 A 14
2 8 A 11
3 10 B 12
4 11 B 11
5 16 C 8
6 18 C 7
您可以使用 dplyr
:
library(dplyr)
df %>% group_by(id,group) %>% slice(1:2) %>% summarise(newcount=sum(count))
管道语法使其易于阅读:按 id
和 group
对数据进行分组,每组取前两行,然后对 counts
[=15 求和=]
您可以使用 data.table
setDT(df)[, list(newcount = sum(count[1:2])), by = .(id, group)]
# id group newcount
#1: 2 A 14
#2: 8 A 11
#3: 10 B 12
#4: 11 B 11
#5: 16 C 8
#6: 18 C 7
我已经找到了一个快速解决我的问题的方法,但我觉得它很迟钝。此外,它使用 for 循环,从我收集的信息来看,在 R 中应该不惜一切代价避免使用循环。感谢整理此代码的任何和所有建议。我对 R 还是很陌生,但我担心我把一个相对简单的问题搞得太复杂了。
我有一个数据集如下:
id count group
2 6 A
2 8 A
2 6 A
8 5 A
8 6 A
8 3 A
10 6 B
10 6 B
10 6 B
11 5 B
11 6 B
11 7 B
16 6 C
16 2 C
16 0 C
18 6 C
18 1 C
18 6 C
我想创建一个新的数据框,其中包含每个唯一 ID 的前两个计数的总和(例如,ID 2 为 6+8=14)。我还想附加正确的组标识符。
通常,当您连续几天测量不同受试者和治疗的值时,您可能需要这样做,并且您想要计算每个受试者在测量的前 x 天的总和。
这是我想出的:
id <- c(rep(c(2,8,10,11,16,18),each=3))
count <- c(6,8,6,5,6,3,6,6,6,5,6,7,6,2,0,6,1,6)
group <- c(rep(c("A","B","C"),each=6))
df <- data.frame(id,count,group)
newid<-c()
newcount<-c()
newgroup<-c()
for (i in 1:length(unique(df$"id"))) {
newid[i] <- unique(df$"id")[i]
newcount[i]<-sum(df[df$"id"==unique(df$"id")[i],2][1:2])
newgroup[i] <- as.character(df$"group"[df$"id"==newid[i]][1])
}
newdf<-data.frame(newid,newcount,newgroup)
一些可能improvements/alternatives我不确定:
- For 循环与应用函数
- 我可以直接在 for 循环内创建数据框,还是应该坚持创建可以稍后分配给数据框的向量?
- accessing/subsetting vectors/columns ($, [], [[]], subset?) 更一致的方法
聚合时可以尝试使用自定义函数
sum1sttwo<-function (x){
return(x[1]+x[2])
}
aggregate(count~id+group, data=df,sum1sttwo)
输出为:
id group count
1 2 A 14
2 8 A 11
3 10 B 12
4 11 B 11
5 16 C 8
6 18 C 7
04/2015 编辑:当您的数据集很大时,dplyr 和 data.table 绝对是更好的选择。 base R 最重要的缺点之一是数据帧太慢。但是,如果你只是需要聚合一个非常simple/small的数据集,base R中的聚合函数就可以达到目的。
library(plyr)
-Keep first 2 rows for each group and id
df2 <- ddply(df, c("id","group"), function (x) x$count[1:2])
-Aggregate by group and id
df3 <- ddply(df2, c("id", "group"), summarize, count=V1+V2)
df3
id group count
1 2 A 14
2 8 A 11
3 10 B 12
4 11 B 11
5 16 C 8
6 18 C 7
您可以使用 dplyr
:
library(dplyr)
df %>% group_by(id,group) %>% slice(1:2) %>% summarise(newcount=sum(count))
管道语法使其易于阅读:按 id
和 group
对数据进行分组,每组取前两行,然后对 counts
[=15 求和=]
您可以使用 data.table
setDT(df)[, list(newcount = sum(count[1:2])), by = .(id, group)]
# id group newcount
#1: 2 A 14
#2: 8 A 11
#3: 10 B 12
#4: 11 B 11
#5: 16 C 8
#6: 18 C 7