Reputation: 43
Variations of this question have been answered, but I am struggling to apply them to my dataset as someone relatively inexperienced with R/programming. I have several data frames and I am trying to use a for loop to create a new variable added to each of the data frames.
Each data frame has the exact same column names, but the data frames represent different time points (e.g., w1 is wave 1, w2 is wave 2, etc.).
I completed a for-loop to 1) reverse score several items, then 2) compute a new variable which is just a sum of several variables.
w1
cesd1 cesd2
0 0
1 1
2 1
w2
cesd1 cesd2
3 0
1 2
2 1
waves = list(w1, w2)
for(i in 1:length(waves)) {
waves[[i]]$cesd2R <- abs(waves[[i]]$cesd2 - 3)
waves[[i]]$cesdTot <- with(waves[[i]], cesd1+ cesd2R, na.rm = T)
}
I would like to get an output that includes all of the previous columns in each data frame PLUS the new columns I compute in the loop ("cesd2R" and "cesdTot") in each of the data frames.
w1
cesd1 cesd2 cesd2R cesdTot
0 0 3 3
1 1 2 3
w2
cesd1 cesd2 cesd2R cesdTot
3 0 3 6
1 2 1 2
When I run the loop, I get no errors but nothing seems to happen. What am I missing? Thank you very much!
Upvotes: 1
Views: 76
Reputation: 43
I got some help from a colleague and solved my problem, which was simply missing the step of assigning "waves" back to each original data frame.
So the original code works:
w1
cesd1 cesd2
0 0
1 1
2 1
w2
cesd1 cesd2
3 0
1 2
2 1
waves = list(w1, w2)
for(i in 1:length(waves)) {
waves[[i]]$cesd2R <- abs(waves[[i]]$cesd2 - 3)
waves[[i]]$cesdTot <- with(waves[[i]], cesd1+ cesd2R, na.rm = T)
}
and I added:
w1 = waves[[1]]
w2 = waves[[2]]
Upvotes: 0
Reputation: 145965
(a) be careful of names, your code uses cesdR2
in one place, but your text and sample data use cesd2R
.
(b) You're giving na.rm = TRUE
as an argument to with()
, which won't work as intended. +
doesn't have space for an na.rm
argument either, so this is one way to do it:
for(i in 1:length(waves)) {
waves[[i]]$cesd2R <- abs(waves[[i]]$cesd2 - 3)
waves[[i]]$cesdTot <- rowSums(waves[[i]][, c("cesd1", "cesd2R")], na.rm = TRUE)
}
because rowSums
does accept an na.rm
argument.
Upvotes: 0
Reputation: 463
Looks like you mistyped while creating your second object in the loop. Instead of cesd2R you typed cesdR2. Does that fix it?
> for(i in 1:length(waves)) {
+ waves[[i]]$cesd2R <- abs(waves[[i]]$cesd2 - 3)
+ waves[[i]]$cesdTot <- with(waves[[i]], cesd1+ cesd2R, na.rm = T)
+ }
> waves
[[1]]
cesd1 cesd2 cesd2R cesdTot
1 0 0 3 3
2 1 1 2 3
3 2 1 2 4
[[2]]
cesd1 cesd2 cesd2R cesdTot
1 3 0 3 6
2 1 2 1 2
3 2 1 2 4
Upvotes: 0