Reputation: 341
I am trying to create a dataframe through a for loop and trying to add a vector for each row of the data frame.
The rows are people and the columns are the name category and points category.
For example I'm trying to have something like...
Name Points
Susie c(12,45,23)
Bill c(13,24,12,89)
CJ c(12)
So far my code looks like
names_list <-c("Susie","Bill","CJ")
result = data.frame()
for (name in names_list){
listing = .....
frame = data.frame(name,listing)
names(frame) = c("name","list")
result <- rbind(result,frame)
}
Where listing happens to be the points associated with that name. However instead of creating 1 row for each name containing all their points, it creates multiple rows with the same name for each point.
Result looks like
1 Susie 12
2 Susie 45
3 Susie 23
4 Bill 13
5 Bill 24
6 Bill 12
7 Bill 89
8 CJ 12
Upvotes: 8
Views: 26500
Reputation: 3535
Name <- c("Suzie", "Bill", "CJ")
Points <- list(c( 12,45,23),
c(13,24,12,89),
c( 12)
)
result <- as.data.frame(cbind(Name, Points))
Then:
print(result)
Gives:
> result
Name Points
1 Suzie 12, 45, 23
2 Bill 13, 24, 12, 89
3 CJ 12
Note:
print(result$Points)
Gives:
> result$Points
[[1]]
[1] 12 45 23
[[2]]
[1] 13 24 12 89
[[3]]
[1] 12
Upvotes: 0
Reputation: 10437
The specific problem you've encountered is due to data.frame
flattening any list inputs. This can be prevented using the identify function I
. For example,
data.frame(a = 1, b = list(c("a", "b")))
doesn't do what you want, but
data.frame(a = 1, b = I(list(c("a", "b"))))
does. A discussion of this behavior and some alternatives are available at http://r4ds.had.co.nz/many-models.html#list-columns-1
You can use I
to produce the desired result using your example as well:
names_list <-c("Susie","Bill","CJ")
points <- list(c(12,45,23),
c(13,24,12,89),
12)
result = data.frame()
for (i in 1:length(names_list)){
frame = data.frame(names_list[[i]], I(points[i]))
names(frame) = c("name","list")
result <- rbind(result,frame)
}
though as pointed out in the comments, there are better ways to do it. All you really need is
data.frame(
name = names_list,
points = I(points))
Upvotes: 12
Reputation: 558
I don't know in what structure your vector value sare but in general to nest vectors in a column you can do something like this:
names <- c("A", "B", "C")
vectors <- list(list(1,2,3), list(4,5,6), list(7,8,9))
as.data.frame(cbind(names, vectors))
names vectors
1 A 1, 2, 3
2 B 4, 5, 6
3 C 7, 8, 9
Upvotes: 3