Trying to plot a time series chart with ggplot2 and using the alpha value to make the lines darkers/lighter, as per ggplot2. Got it working in 1 function but when I try with another dataset the alpha doesnt work. Guess I am calling something incorrectly bc I have the alpha variable set at 0.2 but the line still come out dark
Here is the code and some sample data
tsplot <- ggplot(xall, aes(x=Var1, y=value)) +
geom_line(size=.01) + guides(colour=FALSE) + xlab(x.lab) +ylab("Time Series")
tsplot <- tsplot + aes(alpha=alpha, group= factor(Var2)) +guides(alpha=F)
Sample data for xall
Var1 Var2 value alpha row
1 1 657 0 0.2 Other Rows
2 2 657 -0.006748957 0.2 Other Rows
3 3 657 -0.00088561 0.2 Other Rows
4 4 657 0.009399679 0.2 Other Rows
5 5 657 0.020216333 0.2 Other Rows
6 6 657 0.035222838 0.2 Other Rows
7 7 657 0.038869107 0.2 Other Rows
8 8 657 0.034068491 0.2 Other Rows
9 9 657 0.044237734 0.2 Other Rows
81 1 553 0 0.2 Other Rows
82 2 553 -0.006172511 0.2 Other Rows
83 3 553 -0.004779576 0.2 Other Rows
84 4 553 0.000116964 0.2 Other Rows
85 5 553 -0.013408332 0.2 Other Rows
86 6 553 -0.003200561 0.2 Other Rows
87 7 553 0.000574187 0.2 Other Rows
88 8 553 0.025227017 0.2 Other Rows
89 9 553 0.019984901 0.2 Other Rows
241 1 876 0 0.2 Other Rows
242 2 876 0.006348487 0.2 Other Rows
243 3 876 0.020292484 0.2 Other Rows
244 4 876 0.030155311 0.2 Other Rows
245 5 876 0.02664097 0.2 Other Rows
246 6 876 0.021992971 0.2 Other Rows
247 7 876 0.015871216 0.2 Other Rows
248 8 876 0.020519216 0.2 Other Rows
249 9 876 0.017004875 0.2 Other Rows
250 10 876 0.029588482 0.2 Other Rows
Any help would be greatly appreciated.
You need to add alpha to the global aesthetic. You should also add the group mapping:
ggplot(xall, aes(x=Var1, y=value, alpha=alpha, group= factor(Var2))) +
geom_line(size=.01) + guides(colour=FALSE) + xlab(x.lab) +ylab("Time Series")
Related
I have two data frames, Table1 and Table2.
Table1:
code
CM171
CM114
CM129
CM131
CM154
CM197
CM42
CM54
CM55
Table2:
code;y;diff_y
CM60;1060;2.9
CM55;255;0.7
CM54;1182;3.2
CM53;1046;2.9
CM47;589;1.6
CM42;992;2.7
CM39;1596;4.4
CM36;1113;3
CM34;1975;5.4
CM226;155;0.4
CM224;46;0.1
CM212;43;0.1
CM197;726;2
CM154;1122;3.1
CM150;206;0.6
CM144;620;1.7
CM132;8;0
CM131;618;1.7
CM129;479;1.3
CM121;634;1.7
CM114;15;0
CM109;1050;2.9
CM107;1165;3.2
CM103;194;0.5
I want to add a column to Table2 based on the values in Table1. I tried to do this using dplyr:
result <-Table2 %>%
mutate (fbp = case_when(
code == Table1$code ~"y",))
But this only works for a few rows. Does anyone know why it doesn't add all rows? The values are not repeated.
Try this. It looks like the == operator is only checking for one value. Instead you can use %in% to test all values. Here the code:
#Code
result <-Table2 %>%
mutate (fbp = case_when(
code %in% Table1$code ~"y",))
Output:
code y diff_y fbp
1 CM60 1060 2.9 <NA>
2 CM55 255 0.7 y
3 CM54 1182 3.2 y
4 CM53 1046 2.9 <NA>
5 CM47 589 1.6 <NA>
6 CM42 992 2.7 y
7 CM39 1596 4.4 <NA>
8 CM36 1113 3.0 <NA>
9 CM34 1975 5.4 <NA>
10 CM226 155 0.4 <NA>
11 CM224 46 0.1 <NA>
12 CM212 43 0.1 <NA>
13 CM197 726 2.0 y
14 CM154 1122 3.1 y
15 CM150 206 0.6 <NA>
16 CM144 620 1.7 <NA>
17 CM132 8 0.0 <NA>
18 CM131 618 1.7 y
19 CM129 479 1.3 y
20 CM121 634 1.7 <NA>
21 CM114 15 0.0 y
22 CM109 1050 2.9 <NA>
23 CM107 1165 3.2 <NA>
24 CM103 194 0.5 <NA>
I want to apply a function to rows of a data frame. The function is conditional on the value of one column being greater than the value in another column. If the condition is met I take the element from two (other) columns and multiply them, the result is then added to a new column. If the initial condition is not met there is no multiplication and an original value is copied to the new column.
Create some data:
var0 <- c("A", "B", "C", "D", "E")
var1 <- rep(c(105,200), each = 5)
var2 <- c(110:114, 25:29)
var3 <- rep(c(560,135), each = 5)
var4 <- rep(c(0.5,0.2), each = 5)
my_df <- as.data.frame(cbind(var0, var1, var2, var3, var4))
Have a look at the data:
var0 var1 var2 var3 var4
1 A 105 110 560 0.5
2 B 105 111 560 0.5
3 C 105 112 560 0.5
4 D 105 113 560 0.5
5 E 105 114 560 0.5
6 A 200 25 135 0.2
7 B 200 26 135 0.2
8 C 200 27 135 0.2
9 D 200 28 135 0.2
10 E 200 29 135 0.2
My attempt at writing the code:
apply(my_df, 1, function(x) {
if(x$var3 > x$var1) {
x$output <- x$var2 * x$var4
} else {
x$output <- x$var2
}
return(x)
})
What the result should look like:
var0 var1 var2 var3 var4 output
1 A 105 110 560 0.5 55.0
2 B 105 111 560 0.5 55.5
3 C 105 112 560 0.5 56.0
4 D 105 113 560 0.5 56.5
5 E 105 114 560 0.5 57.0
6 A 200 25 135 0.2 25.0
7 B 200 26 135 0.2 26.0
8 C 200 27 135 0.2 27.0
9 D 200 28 135 0.2 28.0
10 E 200 29 135 0.2 29.0
Because var3 is greater than var1 in the first 5 rows var2 * var4 occurs, in the last 5 rows the condition is not met so var2 is simply copied to the output column.
You don't need to use an apply() function here, you can just use ifelse():
df$output <- ifelse(df$var3 > df$var1, df$var2*df$var4, df$var2)
var0 <- c("A", "B", "C", "D", "E")
var1 <- rep(c(105,200), each = 5)
var2 <- c(110:114, 25:29)
var3 <- rep(560,135, 5)
var4 <- rep(c(0.5,0.2), each = 5)
to avoid numbers to be converted to factors I am using cbind.data.frame instead of as.data.frame of cbind
my_df <-cbind.data.frame(var0, var1, var2, var3, var4)
> str(my_df)
'data.frame': 10 obs. of 5 variables:
$ var0: Factor w/ 5 levels "A","B","C","D",..: 1 2 3 4 5 1 2 3 4 5
$ var1: num 105 105 105 105 105 200 200 200 200 200
$ var2: int 110 111 112 113 114 25 26 27 28 29
$ var3: num 560 560 560 560 560 560 560 560 560 560
$ var4: num 0.5 0.5 0.5 0.5 0.5 0.2 0.2 0.2 0.2 0.2
I then use an ifelse condition to get the new column
>my_df$output=ifelse(my_df$var3>my_df$var1,my_df$var2*my_df$var4,my_df$var2)
> my_df
var0 var1 var2 var3 var4 output
1 A 105 110 560 0.5 55.0
2 B 105 111 560 0.5 55.5
3 C 105 112 560 0.5 56.0
4 D 105 113 560 0.5 56.5
5 E 105 114 560 0.5 57.0
6 A 200 25 560 0.2 5.0
7 B 200 26 560 0.2 5.2
8 C 200 27 560 0.2 5.4
9 D 200 28 560 0.2 5.6
10 E 200 29 560 0.2 5.8
Note I was not getting the same values in var3 as yours. So I changed var3 to be the ones given
> var3 <- c(rep(560,5),rep(135,5))
> var3
[1] 560 560 560 560 560 135 135 135 135 135
> my_df <-cbind.data.frame(var0, var1, var2, var3, var4)
> my_df$output=ifelse(my_df$var3>my_df$var1,my_df$var2*my_df$var4,my_df$var2)
> my_df
var0 var1 var2 var3 var4 output
1 A 105 110 560 0.5 55.0
2 B 105 111 560 0.5 55.5
3 C 105 112 560 0.5 56.0
4 D 105 113 560 0.5 56.5
5 E 105 114 560 0.5 57.0
6 A 200 25 135 0.2 25.0
7 B 200 26 135 0.2 26.0
8 C 200 27 135 0.2 27.0
9 D 200 28 135 0.2 28.0
10 E 200 29 135 0.2 29.0
I want to create some basic grouped barplots with ggplot2 but it seems to exclude some data. If I review my input data everything is there, but some bars are missing and it is also messing with the error bars. I tried to convert into multiple variable types, regrouped, loaded again, saved everything in .csv and loaded all new... I just don't know what is wrong.
Here is my code:
library(ggplot2)
limits <- aes(ymax = DataCm$mean + DataCm$sd,
ymin = DataCm$mean - DataCm$sd)
p <- ggplot(data = DataCm, aes(x = factor(DataCm$Zeit), y = factor(DataCm$mean)
) )
p + geom_bar(stat = "identity",
position = position_dodge(0.9),fill =DataCm$group) +
geom_errorbar(limits, position = position_dodge(0.9),
width = 0.25) +
labs(x = "Time [min]", y = "Individuals per foodsource")
This is DataCm:
Zeit mean sd group
1 30 0.1 0.3162278 1
2 60 0.0 0.0000000 2
3 90 0.1 0.3162278 3
4 120 0.0 0.0000000 4
5 150 0.1 0.3162278 5
6 180 0.1 0.3162278 6
7 240 0.3 0.6749486 1
8 300 0.3 0.6749486 2
9 360 0.3 0.6749486 3
10 30 0.1 0.3162278 4
11 60 0.1 0.3162278 5
12 90 0.2 0.4216370 6
13 120 0.3 0.4830459 1
14 150 0.3 0.4830459 2
15 180 0.4 0.5163978 3
16 240 0.3 0.4830459 4
17 300 0.4 0.5163978 5
18 360 0.4 0.5163978 6
19 30 1.2 1.1352924 1
20 60 1.8 1.6865481 2
21 90 2.2 2.0976177 3
22 120 2.2 2.0976177 4
23 150 2.0 1.8856181 5
24 180 2.3 1.9465068 6
25 240 2.4 2.0655911 1
26 300 2.1 1.8529256 2
27 360 2.0 2.1602469 3
28 30 0.2 0.4216370 4
29 60 0.1 0.3162278 5
30 90 0.1 0.3162278 6
31 120 0.1 0.3162278 1
32 150 0.0 0.0000000 2
33 180 0.1 0.3162278 3
34 240 0.1 0.3162278 4
35 300 0.1 0.3162278 5
36 360 0.1 0.3162278 6
37 30 1.3 1.5670212 1
38 60 1.5 1.5811388 2
39 90 1.5 1.7159384 3
40 120 1.5 1.9002924 4
41 150 1.9 2.1317703 5
42 180 1.9 2.1317703 6
43 240 2.2 2.3475756 1
44 300 2.4 2.3190036 2
45 360 2.2 2.1499354 3
46 30 2.1 2.1317703 4
47 60 3.0 2.2110832 5
48 90 3.3 2.1628171 6
49 120 3.2 2.1499354 1
50 150 3.4 2.6331224 2
51 180 3.5 2.4152295 3
52 240 3.7 2.6267851 4
53 300 3.7 2.4060110 5
54 360 3.8 2.6583203 6
The output is:
Maybe you can help me. Thanks in advance!
Best wishes,
Benjamin
Solved it:
I reshaped everything in Excel and exported it another way. The group variable was also not the way I wanted it. Now it is fixed, but I can't really tell you why.
Your data looks malformed. I guess you wanted to have 6 different group values for each time point, but now the group variable just loops over, and you have:
1 30 0.1 0.3162278 1
...
10 30 0.1 0.3162278 4
...
19 30 1.2 1.1352924 1
...
28 30 0.2 0.4216370 4
geom_bar then probably omits rows that have identical mean and time. Although I am not sure why it chooses to do so, you should solve the group problem first anyway.
I am using Rstudio (version .99.903), have a PC (windows 8). I have a follow up question from yesterday as the problem became more complicated. Here is what the data looks like:
Number Trial ID Open date Enrollment rate
420 NCT00091442 9 1/28/2005 0.2
1476 NCT00301457 26 2/22/2008 1
10559 NCT01307397 34 7/28/2011 0.6
6794 NCT00948675 53 5/12/2010 0
6451 NCT00917384 53 8/17/2010 0.3
8754 NCT01168973 53 1/19/2011 0.2
8578 NCT01140347 53 12/30/2011 2.4
11655 NCT01358877 53 4/2/2012 0.3
428 NCT00091442 55 9/7/2005 0.1
112 NCT00065325 62 10/15/2003 0.2
477 NCT00091442 62 11/11/2005 0.1
16277 NCT01843374 62 12/16/2013 0.2
17386 NCT01905657 62 1/8/2014 0.6
411 NCT00091442 66 1/12/2005 0
What I need to do is compare the enrollment rate of the most current date within a given ID to the average of those values that are up to one year prior to it. For instance, for ID 53, the date of 1/19/2011 has an enrollment rate of 0.2 and I would want to compare this against the average of 8/17/2010 and 5/12/2010 enrollment rates (e.g., 0.15).
If there are no other dates within the ID prior to the current one, then the comparison should not be made. For instance, for ID 26, there would be no comparison. Similarly, for ID 53, there would be no comparison for 5/12/2010.
When I say "compare" I am not doing any analysis or visualization. I simply want a new column that takes the average value of those enrollment rates up to one year prior to the current one (I will be plotting them and percentile ranking them later). There are >20,000 data points. Any help would be much appreciated.
Verbose but possibly high performance way of doing this. No giant for loops looping over all the rows of the data frame. The two sapply loops only operate on a big numeric vector, which should be relatively quick regardless of your data row count. But I'm sure someone will waltz in with a trivial dplyr solution soon enough.
Approach assumes that your data is first sorted by ID then by Opendata. If they are not sorted, you need to sort them first.
# Find indices where the same ID is above and below it
A = which(unlist(sapply(X = rle(df$ID)$lengths,
FUN = function(x) {if(x == 1) return(F)
if(x == 2) return(c(F,F))
if(x >= 3) return(c(F,rep(T, x-2),F))})))
# Store list of date, should speed up code a tiny bit
V_opendate = df$Opendate
# Further filter on A, where the date difference < 365 days
B = A[sapply(A, function(x) (abs(V_opendate[x]-V_opendate[x-1]) < 365) & (abs(V_opendate[x]-V_opendate[x+1]) < 365))]
# Return actual indices of rows - 1, rows +1
C = sapply(B, function(x) c(x-1, x+1), simplify = F)
# Actually take the mean of these cases
D = sapply(C, function(x) mean(df[x,]$Enrollment))
# Create new column rate and fill in with value of C. You can do the comparison from here.
df[B,"Rate"] = D
Number Trial ID Opendate Enrollmentrate Rate
1 420 NCT00091442 9 2005-01-28 0.2 NA
2 1476 NCT00301457 26 2008-02-22 1.0 NA
3 10559 NCT01307397 34 2011-07-28 0.6 NA
4 6794 NCT00948675 53 2010-05-12 0.0 NA
5 6451 NCT00917384 53 2010-08-17 0.3 0.10
6 8754 NCT01168973 53 2011-01-19 0.2 1.35
7 8578 NCT01140347 53 2011-12-30 2.4 0.25
8 11655 NCT01358877 53 2012-04-02 0.3 NA
9 428 NCT00091442 55 2005-09-07 0.1 NA
10 112 NCT00065325 62 2003-10-15 0.2 NA
11 477 NCT00091442 62 2005-11-11 0.1 NA
12 16277 NCT01843374 62 2013-12-16 0.2 NA
13 17386 NCT01905657 62 2014-01-08 0.6 NA
14 411 NCT00091442 66 2005-01-12 0.0 NA
14 411 NCT00091442 66 1/12/2005 0.00 NA
The relevant rows are calculated. You can do your comparison with the newly created Rate column.
You might have to change the code a little since I changed removed the space in the column names
df = read.table(text = " Number Trial ID Opendate Enrollmentrate
420 NCT00091442 9 1/28/2005 0.2
1476 NCT00301457 26 2/22/2008 1
10559 NCT01307397 34 7/28/2011 0.6
6794 NCT00948675 53 5/12/2010 0
6451 NCT00917384 53 8/17/2010 0.3
8754 NCT01168973 53 1/19/2011 0.2
8578 NCT01140347 53 12/30/2011 2.4
11655 NCT01358877 53 4/2/2012 0.3
428 NCT00091442 55 9/7/2005 0.1
112 NCT00065325 62 10/15/2003 0.2
477 NCT00091442 62 11/11/2005 0.1
16277 NCT01843374 62 12/16/2013 0.2
17386 NCT01905657 62 1/8/2014 0.6
411 NCT00091442 66 1/12/2005 0", header = T)
I have a data.frame like so:
df <- data.frame(x = c(998,994,992,990,989,988), y = seq(0.5, 3, by = 0.5))
df
x y
1 998 0.5
2 994 1.0
3 992 1.5
4 990 2.0
5 989 2.5
6 988 3.0
I would like to expand it so the values in x are exactly 1 apart so the final data.frame looks like this:
x y
1 998 0.5
2 997 0.5
3 996 0.5
5 995 0.5
6 994 1.0
7 993 1.0
8 992 1.5
9 991 1.5
10 990 2.0
11 989 2.5
12 988 3.0
You can also use approx:
data.frame(approx(df, xout=max(df$x):min(df$x), method="constant", f=1))
x y
1 998 0.5
2 997 0.5
3 996 0.5
4 995 0.5
5 994 1.0
6 993 1.0
7 992 1.5
8 991 1.5
9 990 2.0
10 989 2.5
11 988 3.0
you can try with function na.locf from package zoo:
all_values <- max(df$x):min(df$x)
na.locf(merge(df, x=all_values, all=TRUE)[rev(seq(all_values)),])
# x y
# 11 998 0.5
# 10 997 0.5
# 9 996 0.5
# 8 995 0.5
# 7 994 1.0
# 6 993 1.0
# 5 992 1.5
# 4 991 1.5
# 3 990 2.0
# 2 989 2.5
# 1 988 3.0
NB
As suggested by #Ananta and #ProcrastinatusMaximus, another option is to set fromLast=TRUE in the na.locf call (if you need to have x in descending order, you'll need to sort the data.frame afterwards):
na.locf(merge(df, x=all_values, all=TRUE), fromLast=TRUE)