R: Loop Over Columns in Data.Table

How to loop through a datatable columns?

We can do this with a for loop by looping over the column names of 'idt'. In this case we get the values of the string, convert it to character and assign (:=) it to the string name or column name ((i))

vec <- names(idt)
for(i in vec) idt[, (i) := as.character(get(i))]

Or using .SDcols, we specify the columns of interest in .SDcols, loop through the Subset of data.table (.SD) with lapply and assign (:=) it to the vector of column names ('vec')

id1[, (vec) := lapply(.SD, as.character), .SDcols = vec]

Looping over columns in data.table R

You can use colSums, which is much simpler and faster than looping.

dt <- data.table(va=c(1,0,1), vb=c(1,0,0), vc=c(1,1,1))
col.names <- c("va", "vc")
dt[, colSums(.SD==1), .SDcols = col.names]
# va vc
# 2 3

Note: I changed your object names to dt and col.names because it is not good practice to use base functions as names.

If you really want to use a for loop (I don't recommend it, but for educational purposes...) you can fix it using get to use the values of the column rather than the column name itself

for (col in col.names) {
dt[get(col) == 1, print(.N)]
}

R: loop through 2 columns to subset a data.table or data.frame

No loop necessary, here's a purely-data.table method.

library(data.table)
setDT(mycondition)
mycondition[, c("c1a", "c1b", "c2a", "c2b") := .(c1-0.5, c1+0.5, c2-0.5, c2+0.5)
][DF, on=.(c1a<=x, c1b>=x, c2a<=y, c2b>=y)
][!is.na(c1), .(x=c1a, y=c2a)]
# x y
# <num> <num>
# 1: 100.01 11.0
# 2: 100.03 10.8
# 3: 100.09 10.9
# 4: 233.45 2.0
# 5: 233.56 2.2

FYI, your code to generate the data is unnecessarily convoluted. The following are functionally equivalent:

DF <- as.data.table(cbind.data.frame(x = c(100.01, 100.03, 100.09, 100.01, 233.45, 233.56, 233.51, 233.45, 561.1, 556.1, 447.23),
y = c(11, 10.8, 10.9, 20, 2, 2.2, 4, 6, 11, 2.1, 10.6)))
DF <- data.table(x = c(100.01, 100.03, 100.09, 100.01, 233.45, 233.56, 233.51, 233.45, 561.1, 556.1, 447.23),
y = c(11, 10.8, 10.9, 20, 2, 2.2, 4, 6, 11, 2.1, 10.6))

mycondition <- cbind.data.frame(c1 = c(100, 233.5), c2 = c(11, 2))
mycondition <- data.frame(c1 = c(100, 233.5), c2 = c(11, 2)) # though not a data.table, as I need above
mycondition <- data.table(c1 = c(100, 233.5), c2 = c(11, 2))

And since you're already using data.table, I suggest you stop using rbind.data.frame, as it is not as featureful (or perhaps safe?) as rbind.data.table, aka rbind(DF, ...). Perhaps better is data.table::rbindlist(list(result1, result2)), as it has some added functionality.

Loop through columns in a data.table and transform those columns

You were on the right track with your second attempt. Here is an approach that uses substitute to build the expression that gets passed in as the 'j' argument in DT[ , j ].

for (i in grep("_", names(DT), value=TRUE)){
e <- substitute(X := X - RF, list(X = as.symbol(i)))
DT[ , eval(e)]
}
DT
# RF S_1 S_2
# [1,] 1 10 20
# [2,] 2 10 20
# [3,] 3 10 20
# [4,] 4 10 20
# [5,] 5 10 20

You could also use an LHS expression rather than a symbol :

for (i in grep("_", names(DT), value=TRUE))
DT[, (i) := get(i)-RF]

Loop through dataframe column names - R

To answer the exact question and fix the code given, see the example below

df <- iris # data

for (i in colnames(df)){
print(class(df[[i]]))
}
# [1] "numeric"
# [1] "numeric"
# [1] "numeric"
# [1] "numeric"
# [1] "factor"
  1. you need to used colnames to get the column names of df.
  2. you access each column using df[[i]] if you want to know the class of that. df[i] is of class data.frame.


Related Topics



Leave a reply



Submit