所以我试图做成对表并保留每对的p值。 请注意,我还是R的初学者。 我的数据看起来像这样(虽然大得多):
a <- factor(c("ID1","ID2","ID3","ID4","ID5"))
b <- runif(5)
b1 <- runif(5)
b2 <- runif(5)
b3 <- runif(5)
c1 <- runif(5)
c2 <- runif(5)
c3 <- runif(5)
df <- data.frame(a,b1,b2,b3,c1,c2,c3)
其中b1,b2,b3应与每行的c1,c2,c3进行比较(对于a列中的每个ID)。 最终结果应该是:
a <- cbind(a,Adjusted_P_Values)
头部(a,1)看起来像:
head(a,1)
a b1 b2 b3 c1 c2
1 ID1 0.1337694 0.7347543 0.5808391 0.4324976 0.5378458
c3 Adjusted_P_value
1 0.6368778 0.99
其中每一行都有相应的P值。
我发现我能想到的一个功能是pairwise.t.test
。
(目前,我只是为每一行运行一个循环并进行正常的t检验然后用p.adjust进行纠正,但我不能做汇总的sd ---我想要这样做。)
所以我现在的问题是如何构建数据以便R喜欢它。我可以使用reshape2库中的melt.data.frame
,但它不会给我正确的结构。
我这样用它:
Test_Data <- melt(df, "a", c("b1","b2","b3","c1","c2","c3"))
但我放松了行的对称性。
因为,当我现在pairwise.t.test
时,我必须使用&#34; a&#34;列或&#34;变量&#34;由melt创建的列,因此我要么在重复之间或ID之间进行比较。
所以,我的问题只是:
我如何构建数据,以便测试每一行,并获得每行的p值,并且每个处理(b或c)具有基于所有行的标准偏差(所有b的一个sd&#39; s和所有c的一个?
我一直在寻找类似的问题(以及关于pairwise.t.test的教程),但没有成功。
答案 0 :(得分:2)
使用tidyverse包的可能解决方案。
首先,将数据框的格式调整为以下结构。
static <T> FlowableTransformer<T, T> requestObserveOn(Scheduler scheduler) {
return f -> new RequestObserveOn<>(f, scheduler);
}
static final class RequestObserveOn<T> extends Flowable<T> {
final Flowable<T> source;
final Scheduler scheduler;
RequestObserveOn(Flowable<T> source, Scheduler scheduler) {
this.source = source;
this.scheduler = scheduler;
}
@Override
protected void subscribeActual(Subscriber<? super T> s) {
source.subscribe(new RequestObserveOnSubscriber<>(s, scheduler.createWorker()));
}
static final class RequestObserveOnSubscriber<T>
extends AtomicLong
implements FlowableSubscriber<T>, Subscription, Runnable {
private static final long serialVersionUID = 3167152788131496136L;
final Subscriber<? super T> actual;
final Worker worker;
final Runnable requestOne;
Subscription upstream;
volatile T item;
Throwable error;
volatile boolean done;
long emitted;
boolean terminated;
RequestObserveOnSubscriber(Subscriber<? super T> actual,
Scheduler.Worker worker) {
this.actual = actual;
this.worker = worker;
this.requestOne = () -> upstream.request(1L);
}
@Override
public void onSubscribe(Subscription s) {
upstream = s;
actual.onSubscribe(this);
worker.schedule(requestOne);
}
@Override
public void onNext(T t) {
item = t;
worker.schedule(this);
}
@Override
public void onError(Throwable t) {
error = t;
done = true;
worker.schedule(this);
}
@Override
public void onComplete() {
done = true;
worker.schedule(this);
}
@Override
public void run() {
if (terminated) {
return;
}
for (;;) {
boolean d = done;
T v = item;
boolean empty = v == null;
if (d && empty) {
Throwable ex = error;
if (ex != null) {
actual.onError(ex);
} else {
actual.onComplete();
}
worker.dispose();
terminated = true;
return;
}
long e = emitted;
if (!empty && e != get()) {
item = null;
actual.onNext(v);
emitted = e + 1;
worker.schedule(requestOne);
} else {
break;
}
}
}
@Override
public void request(long n) {
BackpressureHelper.add(this, n);
worker.schedule(this);
}
@Override
public void cancel() {
upstream.cancel();
worker.dispose();
item = null;
}
}
}
其次,拆分数据框并进行library(tidyverse)
df2 <- df %>%
gather(Column, Value, -a) %>%
extract(Column, into = c("Group", "Number"), regex = "([A-Za-z]+)([0-9]+)")
df2
# a Group Number Value
# 1 ID1 b 1 0.640310605
# 2 ID2 b 1 0.009495756
# 3 ID3 b 1 0.232550506
# 4 ID4 b 1 0.666083758
# 5 ID5 b 1 0.514251141
# 6 ID1 b 2 0.693591292
# 7 ID2 b 2 0.544974836
# 8 ID3 b 2 0.282733584
# 9 ID4 b 2 0.923433484
# 10 ID5 b 2 0.292315840
# 11 ID1 b 3 0.837295628
# 12 ID2 b 3 0.286223285
# 13 ID3 b 3 0.266820780
# 14 ID4 b 3 0.186722790
# 15 ID5 b 3 0.232225911
# 16 ID1 c 1 0.316612455
# 17 ID2 c 1 0.302693371
# 18 ID3 c 1 0.159046003
# 19 ID4 c 1 0.039995918
# 20 ID5 c 1 0.218799541
# 21 ID1 c 2 0.810598552
# 22 ID2 c 2 0.525697547
# 23 ID3 c 2 0.914658166
# 24 ID4 c 2 0.831345047
# 25 ID5 c 2 0.045770263
# 26 ID1 c 3 0.456091482
# 27 ID2 c 3 0.265186672
# 28 ID3 c 3 0.304672203
# 29 ID4 c 3 0.507306870
# 30 ID5 c 3 0.181096208
,然后提取P值。
pairwise.t.test
最后,将P值作为新列添加到原始数据框中。
p_value <- df2 %>%
split(.$a) %>%
map(function(x) pairwise.t.test(x$Value, x$Group, paired = TRUE)) %>%
map_dbl("p.value")
p_value
# ID1 ID2 ID3 ID4 ID5
# 0.3391364 0.5043753 0.4598274 0.6764142 0.1178471
数据强>
df_final <- df %>% mutate(Adjusted_P_value = p_value)
df_final
# a b1 b2 b3 c1 c2 c3 Adjusted_P_value
# 1 ID1 0.640310605 0.6935913 0.8372956 0.31661245 0.81059855 0.4560915 0.3391364
# 2 ID2 0.009495756 0.5449748 0.2862233 0.30269337 0.52569755 0.2651867 0.5043753
# 3 ID3 0.232550506 0.2827336 0.2668208 0.15904600 0.91465817 0.3046722 0.4598274
# 4 ID4 0.666083758 0.9234335 0.1867228 0.03999592 0.83134505 0.5073069 0.6764142
# 5 ID5 0.514251141 0.2923158 0.2322259 0.21879954 0.04577026 0.1810962 0.1178471
为了将P值正确映射回数据帧,必须在“a”列上对数据帧进行排序。
答案 1 :(得分:2)
我的方法与其他答案略有不同,通过时间测量(1 - 3)将数据分为两列,b
和c
,然后使用t.test(...,paired=TRUE)
进行操作成对t检验。
set.seed(1234)
a <- factor(c("ID1","ID2","ID3","ID4","ID5"))
b <- runif(5)
b1 <- runif(5)
b2 <- runif(5)
b3 <- runif(5)
c1 <- runif(5)
c2 <- runif(5)
c3 <- runif(5)
df <- data.frame(a,b1,b2,b3,c1,c2,c3)
library(tidyr)
library(dplyr)
df %>%
gather(.,key="variable",value="value",-a) %>%
extract(.,variable,into = c("measure", "time"),
regex = "([A-Za-z]+)([0-9]+)") %>%
spread(.,measure,value) -> spreadData
# split by ID to conduct paired t-tests by ID
dataList <- split(spreadData,spreadData$a)
pValues <- unlist(lapply(dataList,function(x){
t.test(x$b,x$c,paired=TRUE)$p.value
}))
df$p.value <- pValues
df
...和输出:
> df
a b1 b2 b3 c1 c2
1 ID1 0.640310605 0.6935913 0.8372956 0.31661245 0.81059855
2 ID2 0.009495756 0.5449748 0.2862233 0.30269337 0.52569755
3 ID3 0.232550506 0.2827336 0.2668208 0.15904600 0.91465817
4 ID4 0.666083758 0.9234335 0.1867228 0.03999592 0.83134505
5 ID5 0.514251141 0.2923158 0.2322259 0.21879954 0.04577026
c3 p.value
1 0.4560915 0.3391364
2 0.2651867 0.5043753
3 0.3046722 0.4598274
4 0.5073069 0.6764142
5 0.1810962 0.1178471
>
注意:如果修改其他答案的代码以包含paired=TRUE
参数,则两个解决方案中的p值匹配。
鉴于这篇关于成对t检验的帖子的评论,我想我会用成对测试来说明发生了什么。基本上对于每个时间段1 - 3,我们从b
值中减去c
值,并对差值运行t检验。由于我们已将数据减少到单个列,因此不需要paired=
参数,但测试产生的结果与传递带有paired=TRUE
参数的2列相同t.test()
。
# alternative 2: subtract b from c and use regular t-test
# to show how pairwise works
spreadData$difference <- spreadData$c - spreadData$b
dataList <- split(spreadData,spreadData$a)
pValues <- unlist(lapply(dataList,function(x){
t.test(x$difference)$p.value
}))
df$p.value <- pValues
df
...和输出:
> spreadData$difference <- spreadData$c - spreadData$b
> dataList <- split(spreadData,spreadData$a)
> pValues <- unlist(lapply(dataList,function(x){
+ t.test(x$difference)$p.value
+ }))
> df$p.value <- pValues
> df
a b1 b2 b3 c1 c2
1 ID1 0.640310605 0.6935913 0.8372956 0.31661245 0.81059855
2 ID2 0.009495756 0.5449748 0.2862233 0.30269337 0.52569755
3 ID3 0.232550506 0.2827336 0.2668208 0.15904600 0.91465817
4 ID4 0.666083758 0.9234335 0.1867228 0.03999592 0.83134505
5 ID5 0.514251141 0.2923158 0.2322259 0.21879954 0.04577026
c3 p.value
1 0.4560915 0.3391364
2 0.2651867 0.5043753
3 0.3046722 0.4598274
4 0.5073069 0.6764142
5 0.1810962 0.1178471
>
答案 2 :(得分:0)
只需添加到Baraliuh解决方案中即可:
map_dbl(“ p.value”)不起作用,但是, map_df(“ p.value”)以我的情况工作