我想知道如何编写loop code
来浏览每个nth
行并执行function
。
例如,
1-我希望sort
每两行降(#1 & #2)
,(3)
和等。
2-我想为每两行mean
,(#1 & #2)
)和等计算var1的(#3
。
例如,我想根据every two rows
列在df
订购ID
:
library(data.table)
ID <- c("229-220", "229-27", "229-321", "229-36")
Var1 <- LETTERS[1:4]
Var2 <- rnorm(4,4,1)
df<- data.frame(ID, Var1, Var2)
setDT(df)
df
ID Var1 Var2
1: 229-220 A 4.497850
2: 229-27 B 2.033383
3: 229-321 C 4.701356
4: 229-36 D 3.527209
预期结果:
### for the first question I'd like to get something similar to this:
ID Var1 Var2
1 229-27 B 2.033383
2 229-220 A 4.497850
3 229-36 D 3.527209
4 229-321 C 4.701356
### for the second question I'd like to get something similar to this:
com mean
A-B 4.49785
C-D 3.527209
我尝试过不同的东西,但没用。
请提供答案或提示让我获得帮助,而不仅仅是简单地投票!
答案 0 :(得分:1)
要解决您的问题,您可以通过选择每一行并与前一行进行比较来简单地执行操作...简而言之,您使用seq()来获取偶数行的索引(2,4,6和等等)并将ID或计算方法与前面的行组合在一起。
seq(2, nrow(df), by = 2)
[1] 2 4
要解决第1部分,您可以应用此策略并根据ID对数据表的每个2行切片进行排序。
do.call(rbind, lapply(seq(2, nrow(df), by = 2), (function(i){
slice <- df[(i-1):i,]
slice <- slice[order(slice$ID, decreasing = T),]
rownames(slice) <- NULL
slice
})))
ID Var1 Var2
1: 229-27 B 3.430371
2: 229-220 A 6.201931
3: 229-36 D 4.756426
4: 229-321 C 3.467930
使用相同的方法和lapply,这个地址意味着以data.table-wise方式计算。
do.call(rbind, lapply(seq(2, nrow(df), by = 2), (function(i){
data.frame(com = paste(df$Var1[c((i-1):i)], collapse = "-"),
mean = mean(df$Var2[((i-1):i)]))
})))
com mean
1 A-B 4.816151
2 C-D 4.112178
答案 1 :(得分:1)
这是一个选项。我们可以使用dplyr
包。关键是使用mutate(Group = rep(1:(n()/2), each = 2))
来创建所需的组。 df2
是您的第一个所需输出。 df3
是您想要的第二个输出。
library(dplyr)
df2 <- df %>%
mutate(Group = rep(1:(n()/2), each = 2)) %>%
arrange(Group, desc(Var1)) %>%
select(-Group)
df3 <- df %>%
mutate(Group = rep(1:(n()/2), each = 2)) %>%
group_by(Group) %>%
summarise(com = paste(Var1, collapse = "-"),
mean = mean(Var2)) %>%
ungroup() %>%
select(com, mean)