R中的pairwise.t.test的数据操作

时间:2018-01-27 17:53:39

标签: r data-manipulation

所以我试图做成对表并保留每对的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的教程),但没有成功。

3 个答案:

答案 0 :(得分:2)

使用包的可能解决方案。

首先,将数据框的格式调整为以下结构。

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)将数据分为两列,bc,然后使用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值匹配。

替代方法:对c和b

之间的差异进行t检验

鉴于这篇关于成对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”)以我的情况工作