I have a data.table which looks like:
>DT
ID Year Value ABC_1 ABC_2 ABC_3
1: 3 2015 5 0 1 0
2: 4 2015 2 1 0 1
3: 5 2015 1 0 1 1
What I want to do for each ABC_... is:
> unique(DT[Year == 2015 & ABC_1 == 1, .(Year = Year, ABC = ABC_1, N = .N, MEAN = mean(Value))])
Year ABC N MEAN
1: 2015 1 1 2
> unique(DT[Year == 2015 & ABC_2 == 1, .(Year = Year, ABC = ABC_2, N = .N, MEAN = mean(Value))])
Year ABC N MEAN
1: 2015 1 2 3
> unique(DT[Year == 2015 & ABC_3 == 1, .(Year = Year, ABC = ABC_3, N = .N, MEAN = mean(Value))])
Year ABC N MEAN
1: 2015 1 2 1.5
I have over 20 columns with ABC_... and I would like to put this statement in a for-loop. My problem is that the selection / rule needs the column name. It doesn't work with that:
> abc_name <- names(DT)[names(DT) %like% 'ABC']
> abc_name
[1] "ABC_1" "ABC_2" "ABC_3"
> abc_row<- data.table(Year=0, ABC=0, N=0, MEAN=0)
> for (i in 1: length(abc_name)){
+
+ temp_row <- unique(DT[Year == 2015 & abc_name[i] == 1, .(Year = Year, ABC = abc_name[i], N = .N, MEAN = mean(Value))])
+ abc_row <- rbind(abc_row, temp_row)
+ }
> abc_row
Year ABC N MEAN
1: 0 0 0 0
temp_row is empty... When I change the abc_name[I]
with ABC_1
it works:
> abc_name <- names(DT)[names(DT) %like% 'ABC']
> abc_name
[1] "ABC_1" "ABC_2" "ABC_3"
> abc_row<- data.table(Year=0, ABC=0, N=0, MEAN=0)
> for (i in 1: length(abc_name)){
+
+ temp_row <- unique(DT[Year == 2015 & ABC_1 == 1, .(Year = Year, ABC = ABC_1, N = .N, MEAN = mean(Value))])
+ abc_row <- rbind(abc_row, temp_row)
+ }
> abc_row
Year ABC N MEAN
1: 0 0 0 0
2: 2015 1 1 2
3: 2015 1 1 2
4: 2015 1 1 2
How can I use the abc_name
in a for-loop that my script works? I hope you understand my question and someone can help me.
Loop through the name vector ('abc_name') using lapply
, apply the logic in the OP's post, get the value of the column with get
and rbind
the list
elements.
lst <- lapply(abc_name, function(nm)
unique(DT[Year == 2015 & get(nm) == 1,
.(Year = Year, ABC = get(nm), N = .N, MEAN = mean(Value))]))
rbindlist(lst)
# Year ABC N MEAN
#1: 2015 1 1 2.0
#2: 2015 1 2 3.0
#3: 2015 1 2 1.5
Or another option is melt
to reshape the 'wide' to 'long' format, grouped by 'variable' and 'year', and specifying the logical index in 'i' ( value==1
), summarise the dataset
melt(DT, measure = abc_name)[value==1, .(ABC=1, N= .N,
MEAN= mean(Value)), .(variable, Year)][, variable := NULL][]
# Year ABC N MEAN
#1: 2015 1 1 2.0
#2: 2015 1 2 3.0
#3: 2015 1 2 1.5
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.