Reputation: 87
I was working on problem with data.tables. Basically I am search the data.table for set_a
and checking for a Average
is greater than 80 and doing some matrix building. My criteria look for a set_a
value and if it is greater than 80 I want to paste together only the top value as shown below in my script to create a row composed of set_a
, set_b
concatenated with the letter a, value
and then append another row with set_a
, set_b
concatenated letter b, value
into a master table mn. If it isn't greater than 80 than I want select the 1 and 2 value ordered by Average
in descending. I was able to accomplish the first part of the loop but it doesn't continue on for the set_a
values b
and c
. You will also see t
where I tried creating a second data table for the else part of the loop but have been unable to access values for the columns like I would normally in data.frames.
Example data_set:
set_a <- c("a","a","a","a","b","b","b","b","c","c","c","c")
set_b <- c("red","red","red","red","red","red","red","red","red","red","red","red")
value <- c(42,68,90,91,22,65,89,98,78,88,91,33)
Average <- c(94,3,2,1,50,40,5,5,80,9,1,1)
a = data.frame(set_a,set_b,value,Average)
library(data.table)
a = data.table(a)
mn <- c() #create matrix to fill
mn0 <- c() #temp matrix
colu = unique(as.character(a$set_a))
colu2 = as.character(a$set_b)
for (i in seq_along(colu))
{
if (a[set_a[i] == colu[i], max(Average) > 80])#if the average is greater than 80 paste row variables in table.
{
mn <- (cbind(set_a[i],paste0(set_b[i],"_a"),value[i]))
mn0 <- rbind(mn,mn0)
mn2 <- (cbind(set_a[i],paste0(set_b[i],"_b"),value[i]))
mn0 <- rbind(mn0,mn2)
break
}else
{
t = a[set_a == colu[i],.SD[1:2]] #create a second data table to select for
#first second value
mn3 <- cbind(set_a[i],paste0(set_b[i],"_a"),value[i])
mn0 <- rbind(mn0,mn3)
mn4 <- cbind(set_a[i],paste0(set_b[i],"_b"),value[i])
mn0 <- rbind(mn0,mn4)
}
}
mn0
My current result:
[,1] [,2] [,3]
[1,] "a" "red_a" "42"
[2,] "a" "red_b" "42"
Desired result:
[,1] [,2] [,3]
[1,] "a" "red_a" "42"
[2,] "a" "red_b" "42"
[3,] "b" "red_a" "22"
[4,] "b" "red_b" "65"
[5,] "c" "red_a" "78"
[6,] "c" "red_b" "88"
Upvotes: 0
Views: 98
Reputation: 4282
You have a break
inside the if
. It will cause your code to exit the for-loop
. Also, on the else
block, you need to refer to temporary data.table "t", otherwise, set_a will refer to the data.table "a".
Here is the correct script:
mn <- c() #create matrix to fill
mn0 <- c() #temp matrix
colu = unique(as.character(a$set_a))
colu2 = as.character(a$set_b)
for (i in seq_along(colu))
{
if (a[set_a == colu[i], max(Average) > 80])#if the average is greater than 80 paste row variables in table.
{
mn <- (cbind(set_a[i],paste0(set_b[i],"_a"),value[i]))
mn0 <- rbind(mn,mn0)
mn2 <- (cbind(set_a[i],paste0(set_b[i],"_b"),value[i]))
mn0 <- rbind(mn0,mn2)
}else
{
t = a[set_a == colu[i],.SD[1:2]] #create a second data table to select for
#first second value
mn3 <- cbind(as.character(t$set_a[1]),paste0(t$set_b[1],"_a"),t$value[1])
mn0 <- rbind(mn0,mn3)
mn4 <- cbind(as.character(t$set_a[2]),paste0(t$set_b[2],"_b"),t$value[2])
mn0 <- rbind(mn0,mn4)
}
}
mn0
Upvotes: 1