简体   繁体   中英

loop through columns of data frame in r

I have the following problem:

levelsvar <- c("arrears", "expenses", "warmhome", "telephone", "colorTV", "washer", "car", "meatfish", "holiday")

variables <- NULL

for (i in 1:length(levelsvar)) {

variables <- sapply(levelstest, function(x) (length(test$levelsvar[i][test$country==x & test$levelsvar[i]=="1"]) + length(test$levelsvar[i][test$country==x & test$levelsvar[i]=="2"])) / length(test$levelsvar[i][test$country==x]))

} 

I want to use a for loop to perform the function you can see above 9 times for all the levels of "levelsvar". I tried it various times but I failed. I think the problem is that r reads

test$"arrears"

instead of

test$arrears

I already tried to use noquote() but it didn't help.

Do you have a solution to this problem?

Thank you in advance!

edit:

with example

levelstest <- c("AT", "BE")

levelsvar <- c("arrears", "expenses", "warmhome", "telephone", "colorTV", "washer", "car", "meatfish", "holiday")

structure(list(country = c("AT", "AT", "AT", "BE", "BE", "BE"
), arrears = c(1L, 1L, 1L, 2L, 1L, 1L), expenses = c(3L, 1L, 
3L, 1L, 1L, 2L), warmhome = c(1L, 2L, 2L, 1L, 1L, 1L), telephone = c(4L, 
1L, 4L, 4L, 3L, 3L), colorTV = c(2L, 1L, 3L, 4L, 3L, 1L), washer = c(4L, 
1L, 3L, 3L, 1L, 2L), car = c(4L, 4L, 4L, 4L, 3L, 2L), meatfish = c(2L, 
1L, 1L, 4L, 1L, 1L), holiday = c(2L, 2L, 1L, 3L, 4L, 2L)), .Names = c("country", 
"arrears", "expenses", "warmhome", "telephone", "colorTV", "washer", 
"car", "meatfish", "holiday"), row.names = c(NA, 6L), class = "data.frame")

Now I tried

variables <- NULL

for (i in 1:length(levelsvar)) {

variables <- sapply(levelstest, function(x) (length(test[levelsvar[i]][test$country==x & test[levelsvar[i]]=="1"]) + length(test[levelsvar[i]][test$country==x & test[levelsvar[i]]=="2"])) / length(test[levelsvar[i]][test$country==x]))

  }

but this doesn't work.

What I wanted to achieve is to get the percentage for (length(test$arrears[test$country==x & test$arrears=="1"]) + length(test$arrears[test$country==x & test$arrears=="2"])) / length(test$arrears[test$country==x])) for all the levels of levelsvar (with values 1 and 2) and all countries in levelstest .

The solution to my problem is the following:

test <- (structure(list(country = c("AT", "AT", "AT", "BE", "BE", "BE"
), arrears = c(1L, 1L, 1L, 2L, 1L, 1L), expenses = c(3L, 1L, 
                                                 3L, 1L, 1L, 2L), warmhome = c(1L, 2L, 2L, 1L, 1L, 1L), telephone = c(4L, 
                                                                                                                      1L, 4L, 4L, 3L, 3L), colorTV = c(2L, 1L, 3L, 4L, 3L, 1L), washer = c(4L, 
                                                                                                                                                                                           1L, 3L, 3L, 1L, 2L), car = c(4L, 4L, 4L, 4L, 3L, 2L), meatfish = c(2L, 
                                                                                                                                                                                                                                                              1L, 1L, 4L, 1L, 1L), holiday = c(2L, 2L, 1L, 3L, 4L, 2L)), .Names = c("country", 
                                                                                                                                                                                                                                                                                                                                    "arrears", "expenses", "warmhome", "telephone", "colorTV", "washer", 
                                                                                                                                                                                                                                                                                                                                    "car", "meatfish", "holiday"), row.names = c(NA, 6L), class = "data.frame"))

levelsvar <- c("arrears", "expenses", "warmhome", "telephone", "colorTV", "washer", "car", "meatfish", "holiday")

levelstest <- c("AT", "BE")

variables <- NULL

for (i in 1:length(levelsvar)) {

variables <- cbind(variables, sapply(levelstest, function(x) (length(test[levelsvar[i]][test[1]==x & test[levelsvar[i]]=="1"]) + length(test[levelsvar[i]][test[1]==x & test[levelsvar[i]]=="2"])) / length(test[levelsvar[i]][test[1]==x])))

  } 

All you need is test and this:

apply(test[-1],MARGIN = 2,function(x){
  tapply(x,test$country,function(y){
    sum(y %in% c(1,2))/length(y)
  })
})

apply() with margin = 2 will go along your columns, and tapply() will calculate a custom function based on a grouping (country). It even keeps your variable names. test[-1] will skip the country column.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM