我有一个数据框:
SampleName <- c(A,A,A,A,B)
NumberofSample <- c(1,2,3,1,4)
SampleResult <- c(3,6,12,12,14)
Data <- data.frame(SampleName,NumberofSample,SampleResult)
head(Data)
SampleName NumberofSample SampleResult
1 A 1 3
2 A 2 6
3 A 3 12
4 A 1 12
4 B 4 14
我的想法是:当SampleResult&lt; 15&amp;&amp; SampleResult&gt; 5,样品A有6个与条件匹配的样品位点,样品B有4个与之匹配的样品位点。所以理想的结果看起来像这样:
SampleName Frequency
1 A 6
2 B 4
我写了类似的东西:
D1<- aggregate(SampleResult~SampleName, Data, function(x)sum(x<15 && x>5))
但我觉得这缺乏像
这样的东西x * Data$NumberofSample[x]
所以我的问题是什么是正确的代码方式?谢谢
答案 0 :(得分:2)
我们可以使用dplyr
。按&#39; SampleName&#39;分组,&#39; NumberofSample&#39;满足基于&#39; SampleResult&#39;的条件并获得sum
library(dplyr)
Data %>%
group_by(SampleName) %>%
summarise(Frequency = sum(NumberofSample[SampleResult < 15 &
SampleResult > 5]))
# A tibble: 2 x 2
# SampleName Frequency
# <chr> <int>
#1 A 6
#2 B 4
如果我们更喜欢aggregate
aggregate(cbind(Frequency = NumberofSample * (SampleResult < 15 &
SampleResult > 5)) ~ SampleName, Data, sum)
# SampleName Frequency
#1 A 6
#2 B 4
请注意&&
的输出是单个TRUE / FALSE值
(1:3 > 1) && (2:4 > 2)
而不是相同长度的逻辑向量
答案 1 :(得分:2)
akrun的解决方案是现货。但恰巧{dplyr}为这种计算提供了便利功能:count
。
在最常见的形式中,它计算每组中的行数。但是,它也可以执行加权总和,在您的情况下,我们只需权衡SampleResult
是否在您选择的边界之间:
Data %>% count(
SampleName,
wt = NumberofSample[SampleResult > 5 & SampleResult < 15]
)
答案 2 :(得分:1)
以下形式的aggregate
可能更简单。我根据您想要的条件对Data
进行分组,然后选择每个组的length
。
inx <- with(Data, 5 < SampleResult & SampleResult < 15)
aggregate(SampleResult ~ SampleName, Data[inx, ], length)
#SampleName SampleResult
#1 A 3
#2 B 1
另一种可能性是
subData <- subset(Data, 5 < SampleResult & SampleResult < 15)
aggregate(SampleResult ~ SampleName, subData, length)
但我认为逻辑索引解决方案更好,因为它的内存使用量更小。