2014-12-28 14 views
6

Soruma Connecting across missing values with geom_line ile yakından ilişkilidir, ancak yinelenen bir takip değil.geom_line() ile seçili NA'lar arasındaki noktaları birbirine bağlayın()

Eksik değerler NA'm var. Veriler, reshape2 paketi ile uzun formda 'erimiş' ve hem geom_points() hem de geom_line() grafiğini çizmek için ggplot2 kullanıyorum. Örnek verilerde sadece bir grubum var, gerçek verilerimde birkaç grubum var. 4 yıldan fazla eksik veriyle ayrılan bir geom_line() bağlantı veri noktaları çizmek istiyorum. Başka bir deyişle, NA ile bitişik 3 satır varsa, data.frame için en az 4 bitişik satır varsa, data.frame için na.rm uygulamayın, data.frame için na.rm uygulayın.

Düzeltme: Not: Veriler eksik olsa bile noktaların bağlandığı bir kitaptan rakamları çoğalıyorum. Eksik verileri birleştiren bölümler için farklı bir linetype veya colour kullanmak daha iyi olurdu, açıklayan bir notla birlikte bir not. Aşağıda, büyük miktarlarda veriyi manipüle etmeye yetecek kadar sıkıcı ve çirkin bir hack var. Daha basit bir yaklaşım için minnettar olacağım ve özellikle verilerdeki ardışık NA'ların örneklerini saymanın basit bir yolunu bulmaya çok hevesliyim.

### ggplot draws geom_line with NAs 

# Data (real-world example, so not exactly MWE) 
df <- 
structure(list(Year = c(1910, 1911, 1912, 1913, 1914, 1915, 1916, 
1917, 1918, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 
1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 
1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 
1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 
1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 
1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 
1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 
1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 
2005, 2006, 2007, 2008, 2009, 2010), variable = structure(c(2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L), .Label = c("France", "Germany", "Sweden", "Japan" 
), class = c("ordered", "factor")), value = c(0.1724, 0.1748, 
0.1752, 0.1777, 0.1778, 0.1953, 0.2132, 0.2242, 0.222, 0.1947, 
NA, NA, NA, NA, NA, 0.113, 0.113, 0.115, 0.112, 0.111, NA, NA, 
0.114, 0.109, 0.113, 0.12, 0.137, 0.15, 0.163, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, 0.116, NA, NA, NA, NA, NA, NA, 0.11, 
NA, NA, NA, 0.122, NA, NA, NA, 0.122, NA, NA, 0.112, NA, NA, 
0.113, NA, NA, 0.101, NA, NA, 0.102, NA, NA, 0.1043, NA, NA, 
0.0906, NA, NA, 0.0964, NA, NA, 0.1052, NA, NA, 0.1043, NA, NA, 
0.1005, NA, NA, 0.1088, NA, NA, 0.101139312657167, 0.0950290025146689, 
0.0901042749371333, 0.09, 0.107249622799665, 0.108891198658843, 
0.115913495389774, 0.110684772282761, 0.113299133836267, 0.111991953059514 
)), .Names = c("Year", "variable", "value"), row.names = 102:202, class = "data.frame") 

varsayılan arsa:

library("ggplot2") 
ggplot(data = df, aes(x = Year, y = value, group = variable, colour = variable, shape = variable)) + 
    geom_point(size = 3) + geom_line() 

enter image description here

kaldırıldı tüm UA'lara ile arsa (Connecting across missing values with geom_line bakınız):

ggplot(data = df, aes(x = Year, y = value, group = variable, colour = variable, shape = variable)) + 
    geom_point(size = 3) + geom_line(data = df[!is.na(df$value), ]) 

enter image description here

istenen arsa:

df2 <- df 
df2[df2$Year == 1922, ]$value <- "-999999" 
df2[df2$Year == 1948, ]$value <- "-999999" 
df2 <- df2[!is.na(df2$value), ] 
df2$value <- as.numeric(df2$value) 
ggplot(data = df2, aes(x = Year, y = value, group = variable, colour = variable, shape = variable)) + geom_point(size = 3) + 
    geom_line() + scale_y_continuous(limit = c(.08, .23)) 

enter image description here

+0

İstediğiniz arsa, saat kuralları ile tutarlı değil. 1950 - 1949 yılları, 1951 - 1956 yılları arasında "NA" olduğu için 1950'deki nokta izole edilmelidir. Her ikisi de> 3 'NA' dizisidir. – jlhoward

cevap

3

Bu yorumun belirtildiği istisna ile "istenen arsa", üretir.

x <- rle(!is.na(df$value)) 
x$values[which(x$lengths>3 & !x$values)] <- TRUE 
indx <- inverse.rle(x) 
library(ggplot2) 
ggplot(df[indx,],aes(x=Year,y=value,color=variable))+ 
    geom_point(size=3)+ 
    geom_line() 

Temel olarak, FALSE olarak NA kodlamak ve TRUE olarak her şey, daha sonra T/F dizilerini belirlemek için çalışma uzunluğu kodlaması gerçekleştirin. FALSE> 3 uzunluğunun herhangi bir dizisi korunmalıdır, bu yüzden TRUE ( NA olmasalar bile) dönüştürürüz, sonra satır tutulması gerekiyorsa TRUE ile bir indeks vektörünü geri kazanmak için ters rle kullanırız. Son olarak, ggplot'da kullanmak için bunu df'a uygularız.

+0

Mükemmel, açıklama için teşekkürler: Daha önce '' rle'' işlevini duymamıştım, sahip olmak harika olacak. Ayrıca seçim kurallarının tutarsız sözlü açıklamamı hakkında da dikkat çekiyorsunuz! – PatrickT