I would like to create a dataframe that essentially would look something like this
Repeating the period from 1 to 10 and assigning the ID 42,574 times
so that I would end up with a 425,740 row dataframe.
I tried to create a dataframe using the following code
periodstring <- as.numeric(gl(10, 42574))
periods <- as.data.frame(periodstring)
but that sorts the numbers and other approaches did not quiete work. Is there a simple way to do this?
Thanks in advance.
Another option using rep:
data.frame(Period=rep(1:10,times=42574),
ID=rep(1:42574,each=10))
Output sample:
Period ID
1 1 1
2 2 1
3 3 1
4 4 1
5 5 1
6 6 1
7 7 1
8 8 1
9 9 1
10 10 1
11 1 2
12 2 2
13 3 2
14 4 2
15 5 2
16 6 2
17 7 2
18 8 2
19 9 2
20 10 2
Related
I am trying to use anti-join exactly as I have done many times to establish which rows across two datasets do not have matches for two specific columns. For some reason I keep getting 0 rows in the result and I can't understand why.
Below are two dummy df's containing the two columns I am trying to compare - you will see one is missing an entry (df1, SITE no2, PLOT no 8) - so when I use anti-join to compare the two dfs, this entry should be returned, but I am just getting a result of 0.
a<- seq(1:3)
SITE <- rep(a, times = c(16,15,1))
PLOT <- c(1:16,1:7,9:16,1)
df1 <- data.frame(SITE,PLOT)
SITE <- rep(a, times = c(16,16,1))
PLOT <- c(rep(1:16,2),1)
df2 <- data.frame(SITE,PLOT)
df1 df2
SITE PLOT SITE PLOT
1 1 1 1
1 2 1 2
1 3 1 3
1 4 1 4
1 5 1 5
1 6 1 6
1 7 1 7
1 9 1 8
1 10 1 9
1 11 1 10
1 12 1 11
1 13 1 12
1 14 1 13
1 15 1 14
1 16 1 15
1 1 1 16
2 2 2 1
2 3 2 2
2 4 2 3
2 5 2 4
2 6 2 5
2 7 2 6
2 8 2 7
2 9 2 8
2 10 2 9
2 11 2 10
2 12 2 11
2 13 2 12
2 14 2 13
2 15 2 14
2 16 2 15
3 1 2 16
3 1
a <- anti_join(df1, df2, by=c('SITE', 'PLOT'))
a
<0 rows> (or 0-length row.names)
I'm sure the answer is obvious but I can't see it.
The answer can be found in the help file.
anti_join() return all rows from x without a match in y.
So reversing the input for df1 and df2 will give you what you expect.
anti_join(df2, df1, by=c('SITE', 'PLOT'))
# SITE PLOT
# 1 2 8
I have a dataset with repeated measures which I want to use to assign IDs. The repeated measures are from a sequence of consecutive days. However, the sequence itself may be unbalanced (e.g., some have more days while others have less, some start with day 1 but a few others may start with 2 or 3). My question is how to create and assign the same ID withinid the same block of sequence. Here is a toy dataset:
days <- data.frame(
day = c(1L,2L,3L,4L,5L,6L,8L,9L,10L,
2L,3L,4L,5L,6L,7L,9L,10L,
1L,2L,4L,5L,6L,8L,9L,10L,
1L,2L,3L,4L,5L,6L,7L,8L,9L,10L)
)
Here is the end result I expect:
id day
1 1 1
2 1 2
3 1 3
4 1 4
5 1 5
6 1 6
7 1 8
8 1 9
9 1 10
10 2 2
11 2 3
12 2 4
13 2 5
14 2 6
15 2 7
16 2 9
17 2 10
18 3 1
19 3 2
20 3 4
21 3 5
22 3 6
23 3 8
24 3 9
25 3 10
26 4 1
27 4 2
28 4 3
29 4 4
30 4 5
31 4 6
32 4 7
33 4 8
34 4 9
35 4 10
Get the difference between adjacent elements and check if it is less than 0, take the cumulative sum
days$id <- cumsum(c(TRUE, diff(days$day) < 0))
I want to create conditional random pairs without using for-loops so I can use the code with large datasets. At first, I create rows with unique IDs and randomly assign two different "types" to my rows:
df<-data.frame(id=1:10,type=NA,partner=NA)
df[sample(df$id,nrow(df)/2),"type"]<-1 ##random 50% type 1
df[which(is.na(df$type)==TRUE),"type"]<-2 ##other 50% type 2
df
id type partner
1 1 2 NA
2 2 1 NA
3 3 1 NA
4 4 1 NA
5 5 2 NA
6 6 1 NA
7 7 1 NA
8 8 2 NA
9 9 2 NA
10 10 2 NA
Now I want them to receive a random partner of the opposite type. So I randomize my type 1 IDs and match them to some type 2 IDs like so:
df$partner[which(df$type==2)]<-sample(df$id[which(df$type==1)],
nrow(df)/2)
df
id type partner
1 1 2 4
2 2 1 NA
3 3 1 NA
4 4 1 NA
5 5 2 2
6 6 1 NA
7 7 1 NA
8 8 2 6
9 9 2 3
10 10 2 7
And that's where I'm stuck. For some reason I can't think of a vectorized way to tell R "take the IDs of type 1, look where these IDs are in df$partner and return the corresponding row ID as df$partner instead of NA".
One example for a for-loop for conditional random pairing can be found here: click
I'm pretty sure that that's very basic and doable, however, any help appreciated!
Presumably, you want the type 1 and type 2 matched together to have each other's id in their respective partner entries. Fully vectorized solution.
# Define number of ids
n = 100
# Generate startingn data frame
df = data.frame(id = 1:n, type = NA, partner = NA)
# Generate the type column
df$type[(a<-sample(df$id, n/2))] = 1
df$type[(b<-setdiff(1:100, a))] = 2
# Select a random partner id from the other type
df$partner[a] = sample(df$id[b])
# Fill in partner values based on previous line
df$partner[b] = df$id[match(df$id[b], df$partner)]
Output:
id type partner
1 2 11
2 1 13
3 2 19
4 2 10
5 1 17
6 2 28
7 2 27
8 2 21
9 1 22
10 1 4
11 1 1
12 2 20
13 2 2
14 2 25
15 2 24
16 2 30
17 2 5
18 2 29
19 1 3
20 1 12
21 1 8
22 2 9
23 2 26
24 1 15
25 1 14
26 1 23
27 1 7
28 1 6
29 1 18
30 1 16
Newbie, so please be gentle. On Windows 10,trying to read a csv file into R (by row (across), if possible), create a 60X4 matrix and access the data by "cell". When I try to access row 2 column 3 (for example), I get ALL of column 3 returned. I only want the one piece of data. What am I doing wrong?
> A <- read.csv("xxx.csv",header=TRUE)
> B <- matrix(A,nrow=60,ncol=4,byrow=TRUE)
> B[2,3]
[[1]]
[1] 1 2 4 2 5 2 2 2 8 9 3 12 2 9 6 12 4 8 6 12 7 9 12 9 4 2 8 3 3 3 1 3 2 2 2 2 1 1 1 1 3 1 1 2 3 1 2 3 4 3 2 1 1 1 2 2 1 1 1
I would like to refer to values in a data frame column with the row index being dependent on the value of another column.
Example:
value lag laggedValue
1 1 2
2 2 4
3 3 6
4 2 6
5 1 6
6 3 9
7 3 10
8 1 9
9 1 10
10 2
In Excel I use this formula in column "laggedValue":
=INDIRECT("B"&(ROW(B2)+C2))
How can I do this in an R data frame?
Thanks!
For row r with associated lag value lag[r] it looks like you're trying to create a new column that is the (r+lag[r])th element of value (or a missing value if this is out of bounds). You can do this with:
dat$laggedValue <- dat$value[seq(nrow(dat)) + dat$lag]
dat
value lag laggedValue
1 1 1 2
2 2 2 4
3 3 3 6
4 4 2 6
5 5 1 6
6 6 3 9
7 7 3 10
8 8 1 9
9 9 1 10
10 10 2 NA
Other commenters are mentioning that it looks like you're just adding the value and lag columns because your value column has the elements 1 through 10, but this solution will work even when your value column has other data stored in it.
Assuming the same thing as #rawr here:
dat <- data.frame(value=c(1:10),
lag=c(1,2,3,2,1,3,3,1,1,2))
dat$laggedValue <- dat$value + dat$lag
dat
value lag laggedValue
1 1 1 2
2 2 2 4
3 3 3 6
4 4 2 6
5 5 1 6
6 6 3 9
7 7 3 10
8 8 1 9
9 9 1 10
10 10 2 12