如何为数据帧中的每个组运行一个for循环?

时间:2018-07-16 23:01:12

标签: r for-loop

此问题与this one asked earlier类似,但不完全相同。我想遍历一个大数据集(约500,000行),对于一列中的每个唯一值,我想对另一列中的所有值进行一些处理。

以下是我确认可以正常工作的代码:

df = matrix(nrow=783,ncol=2)
counts = table(csvdata$value)
p = (as.vector(counts))/length(csvdata$value)
D = 1 - sum(p**2)

唯一的问题是,它为整个数据集返回值D,而不是为D相同的每组行返回单独的ID值。

说我有这样的数据:
enter image description here

我将如何做与上面的代码相同的事情,但是为ID相同的每行组而不是整个数据集返回D值?我想这需要一个循环,并创建一个矩阵来存储所有D值,其中ID存入一列,而D的值存入另一列,但不确定。

2 个答案:

答案 0 :(得分:1)

好吧,让我们使用”“简而言之,我希望对具有唯一值“ ID”的每个数据块执行for循环中的任何内容。

通常,您可以按一列中的值对行进行分组(例如"ID"),然后根据每组中其他列中的值/条目执行一些转换。在tidyverse中看起来像这样

library(tidyverse)
df %>%
    group_by(ID) %>%
    mutate(value.mean = mean(value))
## A tibble: 8 x 3
## Groups:   ID [3]
#  ID    value value.mean
#  <fct> <int>      <dbl>
#1 a        13       12.6
#2 a        14       12.6
#3 a        12       12.6
#4 a        13       12.6
#5 a        11       12.6
#6 b        12       15.5
#7 b        19       15.5
#8 cc4      10       10.0

在这里,我们计算每组value的平均值,并将这些值添加到每一行。相反,如果您想汇总值,即每个组仅保留汇总值,则可以使用summarise而不是mutate

library(tidyverse)
df %>%
    group_by(ID) %>%
    summarise(value.mean = mean(value))
## A tibble: 3 x 2
#  ID    value.mean
#  <fct>      <dbl>
#1 a           12.6
#2 b           15.5
#3 cc4         10.0

使用tapplyaveby之一在基数R中可以实现相同的目的。据我了解您的问题陈述,不需要for循环。只需应用一个功能(每组)。


样本数据

df <- read.table(text =
    "ID value
a 13
a 14
a 12
a 13
a 11
b 12
b 19
cc4 10", header = T)

更新

要从评论和聊天中得出结论,这应该是您所追求的。

# Sample data
set.seed(2017)
csvdata <- data.frame(
    microsat = rep(c("A", "B", "C"), each = 8),
    allele = sample(20, 3 * 8, replace = T))

csvdata %>%
    group_by(microsat) %>%
    summarise(D = 1 - sum(prop.table(table(allele))^2))
## A tibble: 3 x 2
#  microsat     D
#  <fct>    <dbl>
#1 A        0.844
#2 B        0.812
#3 C        0.812

请注意,prop.table返回分数,并且比您的(as.vector(counts))/length(csvdata$value)短。还请注意,如果省略ID行,则可以针对所有值(无论group_by)重现结果。

答案 1 :(得分:0)

一个base R选项将会

df1$value.mean <- with(df1, ave(value, ID))