此问题与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
值。
我将如何做与上面的代码相同的事情,但是为ID
相同的每行组而不是整个数据集返回D值?我想这需要一个循环,并创建一个矩阵来存储所有D值,其中ID
存入一列,而D
的值存入另一列,但不确定。
答案 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
使用tapply
,ave
,by
之一在基数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))