2014-09-11 59 views
7

我想知道是否有一種簡單的方法來繪製R中有向二分圖形式中2個列表之間元素位置的變化。例如,列表1和2是字符串向量,不一定包含相同的元素:最簡單的方法來繪製R中兩個有序列表之間的排名變化?

list.1 <- c("a","b","c","d","e","f","g") 

list.2 <- c("b","x","e","c","z","d","a") 

我想產生類似的東西:

The sort of output I am after

我已經在使用的igraph包有輕微的bash,但不能容易地構建了我想,我想象和希望不應該太難。

乾杯。

+2

您的問題在這裏回答:http://stackoverflow.com/a/1457599/602276和http:// stackoverflow。com/a/13244122/602276 – Andrie 2014-09-11 07:53:40

+0

事實上,我看到了這些,但我想我認爲會有一個功能,我沒有意識到這將使繪圖和定製微不足道。 – dcl 2014-09-11 08:06:33

回答

6

這是一個簡單的功能,可以做你想做的事。本質上,它使用match來將元素從一個矢量匹配到另一個矢量,並使用arrows來繪製箭頭。

plotRanks <- function(a, b, labels.offset=0.1, arrow.len=0.1) 
    { 
    old.par <- par(mar=c(1,1,1,1)) 

    # Find the length of the vectors 
    len.1 <- length(a) 
    len.2 <- length(b) 

    # Plot two columns of equidistant points 
    plot(rep(1, len.1), 1:len.1, pch=20, cex=0.8, 
     xlim=c(0, 3), ylim=c(0, max(len.1, len.2)), 
     axes=F, xlab="", ylab="") # Remove axes and labels 
    points(rep(2, len.2), 1:len.2, pch=20, cex=0.8) 

    # Put labels next to each observation 
    text(rep(1-labels.offset, len.1), 1:len.1, a) 
    text(rep(2+labels.offset, len.2), 1:len.2, b) 

    # Now we need to map where the elements of a are in b 
    # We use the match function for this job 
    a.to.b <- match(a, b) 

    # Now we can draw arrows from the first column to the second 
    arrows(rep(1.02, len.1), 1:len.1, rep(1.98, len.2), a.to.b, 
     length=arrow.len, angle=20) 
    par(old.par) 
    } 

幾個示例曲線

par(mfrow=c(2,2)) 
plotRanks(c("a","b","c","d","e","f","g"), 
      c("b","x","e","c","z","d","a")) 
plotRanks(sample(LETTERS, 20), sample(LETTERS, 5)) 
plotRanks(c("a","b","c","d","e","f","g"), 1:10) # No matches 
plotRanks(c("a", "b", "c", 1:5), c("a", "b", "c", 1:5)) # All matches 
par(mfrow=c(1,1)) 

comparing ranks

+0

這絕對是完美的。謝謝。我原以爲會有一個功能作爲現有軟件包的一部分來完成這個功能。 – dcl 2014-09-11 08:04:37

6

下面是使用igraph功能的解決方案。

rankchange <- function(list.1, list.2){ 
    grp = c(rep(0,length(list.1)),rep(1,length(list.2))) 
    m = match(list.1, list.2) 
    m = m + length(list.1) 
    pairs = cbind(1:length(list.1), m) 
    pairs = pairs[!is.na(pairs[,1]),] 
    pairs = pairs[!is.na(pairs[,2]),] 
    g = graph.bipartite(grp, as.vector(t(pairs)), directed=TRUE) 
    V(g)$color = c("red","green")[grp+1] 
    V(g)$label = c(list.1, list.2) 
    V(g)$x = grp 
    V(g)$y = c(length(list.1):1, length(list.2):1) 
    g 
} 

這將構建並繪製從向量圖:

g = rankchange(list.1, list.2) 
plot(g) 

enter image description here

調整顏色方案和象徵,以適應使用中的igraph文檔詳細的選項。

注意這是不全面的測試(只嘗試了您的樣本數據),但你可以看到它是如何建立從代碼中的二分圖。

+0

(+1)不錯的圖片,雖然看起來好多很多這樣簡單的編碼代碼 – 2014-09-11 08:04:14

+2

代碼不會做任何繪圖:)繪圖是一行!訣竅是代碼爲這個問題建立了正確的數據結構--OP可能需要這樣做(儘管它不是我們的工作來猜測OP)。我想你可能會從中刪除幾行。 – Spacedman 2014-09-11 08:08:26

+0

Ooo謝謝你。這絕對有用。 – dcl 2014-09-11 08:11:54

4

隨着GGPLOT2:

v1 <- c("a","b","c","d","e","f","g") 
v2 <- c("b","x","e","c","z","d","a") 

o <- 0.05 
DF <- data.frame(x = c(rep(1, length(v1)), rep(2, length(v2))), 
       x1 = c(rep(1 + o, length(v1)), rep(2 - o, length(v2))), 
       y = c(rev(seq_along(v1)), rev(seq_along(v2))), 
       g = c(v1, v2)) 

library(ggplot2) 
library(grid) 
ggplot(DF, aes(x=x, y=y, group=g, label=g)) + 
    geom_path(aes(x=x1), arrow = arrow(length = unit(0.02,"npc")), 
      size=1, color="green") + 
    geom_text(size=10) + 
    theme_minimal() + 
    theme(axis.title = element_blank(), 
     axis.text = element_blank(), 
     axis.ticks = element_blank(), 
     panel.grid = element_blank()) 

resulting graph

這當然可以在一個功能很容易地纏繞。

+0

在我意識到v1和v2之間的「匹配」正在通過'ggplot'的'group'審美有效地完成之前,不得不盯着這一點!整齊。 – Spacedman 2014-09-11 10:59:59

2

這裏的尼科的結果的概括爲使用數據幀:

plotRanks <- function(df, rank_col, time_col, data_col, color_col = NA, labels_offset=0.1, arrow_len=0.1, ...){ 

    time_vec <- df[ ,time_col] 
    unique_dates <- unique(time_vec) 
    unique_dates <- unique_dates[order(unique_dates)] 

    rank_ls <- lapply(unique_dates, function(d){ 
    temp_df <- df[time_vec == d, ] 
    temp_df <- temp_df[order(temp_df[ ,data_col], temp_df[ ,rank_col]), ] 
    temp_d <- temp_df[ ,data_col] 
    temp_rank <- temp_df[ ,rank_col] 
    if(is.na(color_col)){ 
     temp_color = rep("blue", length(temp_d)) 
    }else{ 
     temp_color = temp_df[ ,color_col] 
    } 
    temp_rank <- temp_df[ ,rank_col] 

    temp_ls <- list(temp_rank, temp_d, temp_color) 
    names(temp_ls) <- c("ranking", "data", "color") 
    temp_ls 
    }) 

    first_rank <- rank_ls[[1]]$ranking 
    first_data <- rank_ls[[1]]$data 
    first_length <- length(first_rank) 

    y_max <- max(sapply(rank_ls, function(l) length(l$ranking))) 
    plot(rep(1, first_length), 1:first_length, pch=20, cex=0.8, 
     xlim=c(0, length(rank_ls) + 1), ylim = c(1, y_max), xaxt = "n", xlab = NA, ylab="Ranking", ...) 

    text_paste <- paste(first_rank, "\n", "(", first_data, ")", sep = "") 
    text(rep(1 - labels_offset, first_length), 1:first_length, text_paste) 
    axis(1, at = 1:(length(rank_ls)), labels = unique_dates) 

    for(i in 2:length(rank_ls)){ 
    j = i - 1 
    ith_rank <- rank_ls[[i]]$ranking 
    ith_data <- rank_ls[[i]]$data 
    jth_color <- rank_ls[[j]]$color 
    jth_rank <- rank_ls[[j]]$ranking 
    ith_length <- length(ith_rank) 
    jth_length <- length(jth_rank) 
    points(rep(i, ith_length), 1:ith_length, pch = 20, cex = 0.8) 
    i_to_j <- match(jth_rank, ith_rank) 
    arrows(rep(i - 0.98, jth_length), 1:jth_length, rep(i - 0.02, ith_length), i_to_j 
     , length = 0.1, angle = 10, col = jth_color) 
    offset_choice <- ifelse(length(rank_ls) == 2, i + labels_offset, i - labels_offset) 
    text_paste <- paste(ith_rank, "\n", "(", ith_data, ")", sep = "") 
    text(rep(offset_choice, ith_length), 1:ith_length, text_paste) 
    } 
} 

以下是使用presidents數據集的偶然重塑的例子:

data(presidents) 
years <- rep(1945:1974, 4) 
n <- length(presidents) 
q1 <- presidents[seq(1, n, 4)] 
q2 <- presidents[seq(2, n, 4)] 
q3 <- presidents[seq(3, n, 4)] 
q4 <- presidents[seq(4, n, 4)] 
quarters <- c(q1, q2, q3, q4) 
q_label <- c(rep("Q1", n/4), rep("Q2", n/4), rep("Q3", n/4), rep("Q4", n/4)) 
q_colors <- c(Q1 = "blue", Q2 = "red", Q3 = "green", Q4 = "orange") 
q_colors <- q_colors[match(q_label, names(q_colors))] 

new_prez <- data.frame(years, quarters, q_label, q_colors) 
new_prez <- na.omit(new_prez) 

png("C:/users/fasdfsdhkeos/desktop/prez.png", width = 15, height = 10, units = "in", res = 300) 
    plotRanks(new_prez[new_prez$years %in% 1960:1970, ], "q_label", "years", "quarters", "q_colors") 
dev.off() 

這將產生一個時間序列排序的情節,並且如果需要追蹤某個觀察值,它會引入顏色:

enter image description here

相關問題