R:写一个循环代码来遍历每个第n行并在datatable中执行一个函数?

时间:2017-08-31 19:02:04

标签: r loops sorting datatable apply

我想知道如何编写loop code来浏览每个nth行并执行function

例如,

1-我希望sort每两行降(#1 & #2)(3&#4)。 2-我想为每两行mean(#1 & #2))和计算var1的(#3&#4

例如,我想根据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

我尝试过不同的东西,但没用。

请提供答案或提示让我获得帮助,而不仅仅是简单地投票!

2 个答案:

答案 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)