Seurat教程 || 分析Cell Hashing数据

Cell Hashing是与NYGC的技术创新小组合作开发的,它使用低聚标记(oligo-tagged)抗体来标记表面蛋白,在每个单细胞上放置一个“样本条形码(sample barcode)”,使得不同的样本可以被多路复用并在单个实验中运行。更多信息,可以参阅Cell Hashing with barcoded antibodies enables multiplexing and doublet detection for single cell genomics

其实我们在去年十月份的时候就关注过这个技术:Cell Hashing||单细胞多模态分析。案牍劳形,一直也没有再写它的文章了。今天我们依然跟着Seurat的官网来看看这个是如何分析的。请注意,如果需要看教程,请看官网。一则受个人的能力所限,一则官网才是更新快和及时的。

这里将简要演示如何在Seurat中处理由Cell Hashing 生成的数据。应用于两个数据集,我们可以成功地将细胞分离到它们的原始样本,并识别出交叉样本双峰(cross-sample doublets)。

多路复用函数HTODemux()实现了以下过程:

  • 我们对标准化的HTO值执行K -medoid聚类,它最初将细胞分离为K(# of samples )+1聚类。
  • 我们计算了HTO的一个“负”分布。对于每个HTO,我们使用平均值最低的群作为背景组。
  • 对于每个HTO,我们对负的聚类拟合一个负的二项分布。我们使用这个分布的0.99分位数作为阈值。
  • 根据这些阈值,每个细胞被划分为阳性或阴性的HTO。
  • 对于一个以上hto呈阳性的细胞被标注为双峰。

数据集描述

  • 数据代来自个不同献血者的外周血单核细胞(PBMCs)。
  • 每个供体的细胞都使用CD45作为哈希抗体进行唯一标记。
  • 随后在10X Chromium v2系统的单一lane上运行。
  • 你可以在这里下载RNA和HTO的计数矩阵,或者从GEO下载FASTQ文件

原教程用的是他们处理好的rds文件,而这个我并没有成功下载,就从GEO中下载了表达谱,自己来构建Seurat的对象,所以会有所不同。这里要注意HTO数据一般和RNA的数据是对应的,对于RNA的我们很熟悉了,但是HTO的数据可能并不熟悉,这就要求我们看看 CITE-seq-Count 的数据处理过程及其输出格式。

CITE-Seq 一般的序列结构:

For CITE-seq-Count, the output looks like this:

OUTFOLDER/
-- umi_count/
-- -- matrix.mtx.gz
-- -- features.tsv.gz
-- -- barcodes.tsv.gz
-- read_count/
-- -- matrix.mtx.gz
-- -- features.tsv.gz
-- -- barcodes.tsv.gz
-- unmapped.csv
-- run_report.yaml

好了我们了解了这个格式其实和10X的基本是一致的,这样我们就不用担心了,先读hto数据来看看。请注意,我们下载的是表达谱。

library(Seurat)
library(readr)


hto<- read_csv("GSM2895283_Hashtag-HTO-count.csv.gz")
Parsed with column specification:
cols(
  .default = col_double(),
  X1 = col_character()
)
See spec(...) for full column specifications.
|=================================================================| 100%    2 MB

hto[1:4,1:4]
# A tibble: 4 x 4
  X1                  GGCGACTAGAGGACGG CATCAAGGTCTTGTCC AAACCTGAGTGATCGG
  <chr>                          <dbl>            <dbl>            <dbl>
1 BatchA-AGGACCATCCAA               30                4               12
2 BatchB-ACATGTTACCGT               16               39               15
3 BatchC-AGCTTACTATCC               26                0               19
4 BatchD-TCGATAATGCGA             2698               22                2
> yhto <- as.data.frame(hto)

rownames(yhto) <- yhto[,1] ; yhto <- yhto[,-1] # 整理行名
yhto[1:4,1:4]
                    GGCGACTAGAGGACGG CATCAAGGTCTTGTCC AAACCTGAGTGATCGG
BatchA-AGGACCATCCAA               30                4               12
BatchB-ACATGTTACCGT               16               39               15
BatchC-AGCTTACTATCC               26                0               19
BatchD-TCGATAATGCGA             2698               22                2
                    TGAGGGAGTACTTAGC
BatchA-AGGACCATCCAA               26
BatchB-ACATGTTACCGT               20
BatchC-AGCTTACTATCC               13
BatchD-TCGATAATGCGA               24

rownames(yhto)
# BatchA-AGGACCATCCAA,BatchB-ACATGTTACCGT,BatchC-AGCTTACTATCC,
#  BatchD-TCGATAATGCGA,BatchE-GAGGCTGAGCTA,BatchF-GTGTGACGTATT,
#  BatchG-ACTGTCTAACGG,BatchH-TATCACATCGGT

# 还有特殊的三行:
# bad_struct;no_match;total_reads

同样的,我们读入RNA的umi数据。

umi  <-  read_tsv("GSM2895282_Hashtag-RNA.umi.txt.gz") 


Parsed with column specification:
cols(
  .default = col_double(),
  GENE = col_character()
)
See spec(...) for full column specifications.
|=================================================================| 100% 3902 MB
yumi <- as.data.frame(umi)
rownames(yumi) <- yumi[,1]
yumi<-yumi[,-1]
 dim(yumi)
[1] 40899 50000   

仅仅是为了好抄代码,我们改一下变量名。

pbmc.umis <- yumi
 pbmc.htos <- yhto

rm(yumi)  #  释放我可怜的内存
rm(yhto)
gc()  

取出RNA和HTO共有的barcode.

# Select cell barcodes detected by both RNA and HTO In the example datasets we have already
# filtered the cells for you, but perform this step for clarity.
joint.bcs <- intersect(colnames(pbmc.umis), colnames(pbmc.htos))

length(joint.bcs)
[1] 39842


# Subset RNA and HTO counts by joint cell barcodes
pbmc.umis <- pbmc.umis[, joint.bcs]
pbmc.htos <- as.matrix(pbmc.htos[, joint.bcs])

# Confirm that the HTO have the correct names
rownames(pbmc.htos)

[1] "BatchA-AGGACCATCCAA" "BatchB-ACATGTTACCGT" "BatchC-AGCTTACTATCC"
 [4] "BatchD-TCGATAATGCGA" "BatchE-GAGGCTGAGCTA" "BatchF-GTGTGACGTATT"
 [7] "BatchG-ACTGTCTAACGG" "BatchH-TATCACATCGGT" "bad_struct"         
[10] "no_match"            "total_reads"        

创建Seurat对象,并添加HTO数据。

# Setup Seurat object
pbmc.hashtag <- CreateSeuratObject(counts = pbmc.umis)

# Normalize RNA data with log normalization
pbmc.hashtag <- NormalizeData(pbmc.hashtag)
# Find and scale variable features
pbmc.hashtag <- FindVariableFeatures(pbmc.hashtag, selection.method = "mean.var.plot")
pbmc.hashtag <- ScaleData(pbmc.hashtag, features = VariableFeatures(pbmc.hashtag))

添加HTO数据作为一个独立的assay.

# Add HTO data as a new assay independent from RNA
pbmc.hashtag[["HTO"]] <- CreateAssayObject(counts = pbmc.htos)
# Normalize HTO data, here we use centered log-ratio (CLR) transformation
pbmc.hashtag <- NormalizeData(pbmc.hashtag, assay = "HTO", normalization.method = "CLR")


head(pbmc.hashtag@meta.data)
                    orig.ident nCount_RNA nFeature_RNA nCount_HTO nFeature_HTO
TGCCAAATCTCTAAGG SeuratProject      84194         8167        350           11
ACTGCTCAGGTGTTAA SeuratProject      72747         7305       7704           11
TTCTTAGTCAACACGT SeuratProject      80714         8601        947           10
CATTCGCCACAGTCGC SeuratProject      71829         7226        759           11
TGGACGCCATCGACGC SeuratProject      68720         7500        444           11
CGAGAAGTCAACTCTT SeuratProject      63290         7395        597           10

看看数据的基本分布:

VlnPlot(pbmc.hashtag, features = c("nFeature_RNA", "nCount_RNA", "nCount_HTO","nFeature_HTO"), ncol = 2)

我们现在先不做过滤,看看是什么结果,然后再来思考我们的数据。看一下基于HTO富集的多复路细胞,这里使用Seurat函数HTODemux()函数将细胞分配回它们的样本上。

# If you have a very large dataset we suggest using k_function = 'clara'. This is a k-medoid
# clustering function for large applications You can also play with additional parameters (see
# documentation for HTODemux()) to adjust the threshold for classification Here we are using the
# default settings
pbmc.hashtag <- HTODemux(pbmc.hashtag, assay = "HTO", positive.quantile = 0.99)

# 下面时提示,不是代码,不要运行
Cutoff for BatchA-AGGACCATCCAA : 62 reads
Cutoff for BatchB-ACATGTTACCGT : 54 reads
Cutoff for BatchC-AGCTTACTATCC : 85 reads
Cutoff for BatchD-TCGATAATGCGA : 88 reads
Cutoff for BatchE-GAGGCTGAGCTA : 69 reads
Cutoff for BatchF-GTGTGACGTATT : 99 reads
Cutoff for BatchG-ACTGTCTAACGG : 157 reads
Cutoff for BatchH-TATCACATCGGT : 91 reads
Cutoff for bad-struct : 6 reads
Cutoff for no-match : 27 reads
Cutoff for total-reads : 362 reads

按照我们的惯例,我们看看这个函数的帮助文档:

?HTODemux 
HTODemux {Seurat}   R Documentation
Demultiplex samples based on data from cell 'hashing'
Description
Assign sample-of-origin for each cell, annotate doublets.

Usage
HTODemux(
  object,
  assay = "HTO",
  positive.quantile = 0.99,
  init = NULL,
  nstarts = 100,
  kfunc = "clara",
  nsamples = 100,
  seed = 42,
  verbose = TRUE
)

这时候我们看看数据metadata的变化,主要是这个函数做了什么。

head(pbmc.hashtag@meta.data)
                    orig.ident nCount_RNA nFeature_RNA nCount_HTO nFeature_HTO
TGCCAAATCTCTAAGG SeuratProject      84194         8167        350           11
ACTGCTCAGGTGTTAA SeuratProject      72747         7305       7704           11
TTCTTAGTCAACACGT SeuratProject      80714         8601        947           10
CATTCGCCACAGTCGC SeuratProject      71829         7226        759           11
TGGACGCCATCGACGC SeuratProject      68720         7500        444           11
CGAGAAGTCAACTCTT SeuratProject      63290         7395        597           10
                           HTO_maxID        HTO_secondID HTO_margin
TGCCAAATCTCTAAGG          bad-struct            no-match 0.24136778
ACTGCTCAGGTGTTAA BatchC-AGCTTACTATCC BatchB-ACATGTTACCGT 2.41473062
TTCTTAGTCAACACGT BatchF-GTGTGACGTATT          bad-struct 0.77349516
CATTCGCCACAGTCGC BatchD-TCGATAATGCGA BatchH-TATCACATCGGT 0.24264615
TGGACGCCATCGACGC          bad-struct BatchH-TATCACATCGGT 0.32077486
CGAGAAGTCAACTCTT BatchF-GTGTGACGTATT BatchE-GAGGCTGAGCTA 0.02388553
                                      HTO_classification
TGCCAAATCTCTAAGG                     bad-struct_no-match
ACTGCTCAGGTGTTAA BatchB-ACATGTTACCGT_BatchC-AGCTTACTATCC
TTCTTAGTCAACACGT          bad-struct_BatchF-GTGTGACGTATT
CATTCGCCACAGTCGC                     BatchD-TCGATAATGCGA
TGGACGCCATCGACGC                              bad-struct
CGAGAAGTCAACTCTT BatchE-GAGGCTGAGCTA_BatchF-GTGTGACGTATT
                 HTO_classification.global             hash.ID
TGCCAAATCTCTAAGG                   Doublet             Doublet
ACTGCTCAGGTGTTAA                   Doublet             Doublet
TTCTTAGTCAACACGT                   Doublet             Doublet
CATTCGCCACAGTCGC                   Singlet BatchD-TCGATAATGCGA
TGGACGCCATCGACGC                   Singlet          bad-struct
CGAGAAGTCAACTCTT                   Doublet             Doublet

运行HTODemux()的输出保存在对象元数据(metadata)中。我们可以看到有多少细胞被分为单细胞、双细胞和阴性/模糊细胞。

> # Global classification results
> table(pbmc.hashtag$HTO_classification.global)

 Doublet Negative  Singlet 
   22650    14520     2672      
# 可见,我们的数据是需要过滤的了,Singlet 居然是最少的,为什么?

用山脊图对选定的hto进行可视化富集的结果。

# Group cells based on the max HTO signal
Idents(pbmc.hashtag) <- "HTO_maxID"
RidgePlot(pbmc.hashtag, assay = "HTO", features = rownames(pbmc.hashtag[["HTO"]])[1:2], ncol = 2)

将HTO信号对象化,以确认singlets中的互斥性.

 levels(pbmc.hashtag)
 [1] "bad-struct"          "BatchA-AGGACCATCCAA" "BatchB-ACATGTTACCGT"
 [4] "BatchC-AGCTTACTATCC" "BatchD-TCGATAATGCGA" "BatchE-GAGGCTGAGCTA"
 [7] "BatchF-GTGTGACGTATT" "BatchG-ACTGTCTAACGG" "BatchH-TATCACATCGGT"
[10] "no-match"          

FeatureScatter(pbmc.hashtag, feature1 = "hto_BatchA-AGGACCATCCAA", feature2 = "hto_BatchE-GAGGCTGAGCTA")

这个hto_BatchA-AGGACCATCCAA是哪里来的,或者它在哪里?

噢噢,我们注意到:

pbmc.hashtag@assays
$RNA
Assay data with 40899 features for 39842 cells
Top 10 variable features:
 mt-Nd1, Malat1, mt-Cytb, IGLC3, IGLC2, IGHA1, mt-Nd4, IGHG2, IGJ, IGHA2 

$HTO
Assay data with 11 features for 39842 cells
First 10 features:
 BatchA-AGGACCATCCAA, BatchB-ACATGTTACCGT, BatchC-AGCTTACTATCC,
BatchD-TCGATAATGCGA, BatchE-GAGGCTGAGCTA, BatchF-GTGTGACGTATT,
BatchG-ACTGTCTAACGG, BatchH-TATCACATCGGT, bad-struct, no-match 

FeatureScatter(pbmc.hashtag, feature1 ="rna_Malat1" , feature2  = "rna_IGLC3")

从哪里取特征的标记是rna_hto_

比较Doublet Negative Singlet 细胞的UMIs数目。

Idents(pbmc.hashtag) <- "HTO_classification.global"
VlnPlot(pbmc.hashtag, features = "nCount_RNA", pt.size = 0.1, log = TRUE)

生成一个用于hto的二维UMAP嵌入。为了简单起见,我们在这里通过 singlets and doublets 进行分组。

# First, we will remove negative cells from the object
pbmc.hashtag.subset <- subset(pbmc.hashtag, idents = "Negative", invert = TRUE)

# Calculate a distance matrix using HTO
hto.dist.mtx <- as.matrix(dist(t(GetAssayData(object = pbmc.hashtag.subset, assay = "HTO"))))

# Calculate tSNE embeddings with a distance matrix
#pbmc.hashtag.subset <- RunTSNE(pbmc.hashtag.subset, distance.matrix = hto.dist.mtx, perplexity = 100)
# tsne 实在是跑不动,等不住,换umap吧
 pbmc.hashtag.subset <- RunPCA(pbmc.hashtag.subset)
pbmc.hashtag.subset <- RunUMAP(pbmc.hashtag.subset,dims=1:10)


DimPlot(pbmc.hashtag.subset)

计算一下各个标签下细胞的差异基因,推测它们的差异会带来什么影响。

pbmc.singlet@misc$mk <- FindAllMarkers(pbmc.,only.pos=T)

 pbmc.hashtag.subset@misc$mk %>% filter(cluster == 'bad-struct')  %>% top_n(10,avg_logFC)
               p_val avg_logFC pct.1 pct.2    p_val_adj    cluster    gene
CALD1   4.269893e-28  1.305611 0.213 0.051 1.746343e-23 bad-struct   CALD1
PTTG1   5.510165e-18  1.308636 0.230 0.075 2.253602e-13 bad-struct   PTTG1
PDHA1   5.757841e-18  1.331648 0.196 0.058 2.354900e-13 bad-struct   PDHA1
SNRNP25 9.296534e-18  1.427055 0.213 0.066 3.802189e-13 bad-struct SNRNP25
MDK     1.299665e-17  1.296846 0.213 0.067 5.315500e-13 bad-struct     MDK
HMGA1   3.069179e-14  1.396448 0.230 0.086 1.255263e-09 bad-struct   HMGA1
HSPB1   4.392379e-10  1.386510 0.248 0.110 1.796439e-05 bad-struct   HSPB1
HMGN2   4.458862e-10  1.458616 0.243 0.108 1.823630e-05 bad-struct   HMGN2
CCT3    1.635818e-09  1.396913 0.243 0.112 6.690333e-05 bad-struct    CCT3
TIMM8B  1.135882e-06  1.335207 0.230 0.117 4.645644e-02 bad-struct  TIMM8B

HTO_classification.global

DimPlot(pbmc.hashtag.subset,group.by="HTO_classification.global")

同样,看两者的差异基因如何。

pbmc.hashtag.subset@misc$mk2 <- FindMarkers(pbmc.hashtag.subset,only.pos=T,ident.1= 'Doublet',group.by="HTO_classification.global")
pbmc.hashtag.subset@misc$mk2  %>% top_n(10,avg_logFC)
                      p_val avg_logFC pct.1 pct.2     p_val_adj
CD52           0.000000e+00  1.370377 0.627 0.102  0.000000e+00
CD74          5.492774e-210  1.491273 0.379 0.079 2.246489e-205
HLA-DRA       8.923196e-155  1.686647 0.266 0.035 3.649498e-150
AIF1          2.244058e-139  1.590655 0.235 0.025 9.177971e-135
FOS           1.498210e-126  1.985102 0.235 0.037 6.127527e-122
LST1          2.400314e-119  1.501267 0.205 0.020 9.817044e-115
LYZ           7.770229e-119  2.013469 0.222 0.033 3.177946e-114
S100A9        1.729465e-101  1.765233 0.226 0.051  7.073339e-97
RP11-1143G9.4  1.297476e-90  1.634986 0.168 0.020  5.306549e-86
S100A8         3.501114e-90  1.719860 0.236 0.071  1.431920e-85


# You can also visualize the more detailed classification result by running Idents(object) <-
# 'HTO_classification' beofre plotting. Here, you can see that each of the small clouds on the
# tSNE plot corresponds to one of the 28 possible doublet combinations.

HTO热图

# To increase the efficiency of plotting, you can subsample cells using the num.cells argument
HTOHeatmap(pbmc.hashtag, assay = "HTO", ncells = 5000)

使用通常的scRNA-seq工作流和可视化细胞,并检查潜在的批次效应。

# Extract the singlets

Idents(pbmc.hashtag)  <- "HTO_classification.global"
pbmc.singlet <- subset(pbmc.hashtag, idents = "Singlet")

# Select the top 1000 most variable features
pbmc.singlet <- FindVariableFeatures(pbmc.singlet, selection.method = "mean.var.plot")

# Scaling RNA data, we only scale the variable features here for efficiency
pbmc.singlet <- ScaleData(pbmc.singlet, features = VariableFeatures(pbmc.singlet))

# Run PCA
pbmc.singlet <- RunPCA(pbmc.singlet, features = VariableFeatures(pbmc.singlet))

# We select the top 10 PCs for clustering and tSNE based on PCElbowPlot
pbmc.singlet <- FindNeighbors(pbmc.singlet, reduction = "pca", dims = 1:10)
pbmc.singlet <- FindClusters(pbmc.singlet, resolution = 0.6, verbose = FALSE)
# pbmc.singlet <- RunTSNE(pbmc.singlet, reduction = "pca", dims = 1:10)
pbmc.singlet <- RunUMAP(pbmc.singlet, reduction = "pca", dims = 1:10)
# Projecting singlet identities on UMAPvisualization
DimPlot(pbmc.singlet, group.by = "HTO_classification")
DimPlot(pbmc.singlet)

接下来该找差异基因了。

pbmc.singlet@misc$mk <- FindAllMarkers(pbmc.singlet,only.pos=T)
Calculating cluster 0

  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=04s  
Calculating cluster 1
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=03s  
Calculating cluster 2
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=02s  
Calculating cluster 3
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=02s  
Calculating cluster 4
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=04s  
Calculating cluster 5
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=02s  
Calculating cluster 6
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=18s  

 pbmc.singlet@misc$mk %>% filter(cluster == "6") %>% top_n(10,avg_logFC)
               p_val avg_logFC pct.1 pct.2     p_val_adj cluster   gene
Rps2    0.000000e+00  3.828804 1.000 0.008  0.000000e+00       6   Rps2
Rps18  1.774313e-299  3.590482 1.000 0.010 7.256762e-295       6  Rps18
Rplp0  5.575846e-297  3.671938 1.000 0.010 2.280465e-292       6  Rplp0
Rps27  3.979973e-290  3.524766 1.000 0.011 1.627769e-285       6  Rps27
Rps8   3.735265e-256  3.513067 1.000 0.013 1.527686e-251       6   Rps8
Ftl1   6.754453e-253  3.719029 1.000 0.014 2.762504e-248       6   Ftl1
Rps19  8.025777e-177  3.566633 1.000 0.025 3.282463e-172       6  Rps19
Fth1   3.847843e-173  3.519539 1.000 0.025 1.573729e-168       6   Fth1
Lgals1 9.363616e-158  3.608453 1.000 0.029 3.829625e-153       6 Lgals1
Malat1 4.534014e-119  4.348673 0.929 0.036 1.854367e-114       6 Malat1

说一说,这一群的差异基因有什么特点。

https://satijalab.org/seurat/v3.2/hashing_vignette.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342