How can I dynamically insert values ​​into a dataframe using R

After clearing some of the survey data from the website, I am having a hard time organizing the data into a useful structure for analysis. The problem is that the data is dynamic, as each reviewer scored anywhere between 0 and 3 subcategories (labeled β€œa”, β€œb”, and β€œc” subcategories). I would like to organize the reviews so that each row is a different reviewer and each column is a subcategory that was graded. If the reviewers chose not to rate the subcategory, I would like the missing data to be "NA". Here's a simplified sample of the data:

vec <- c("a","b","c","stop", "a","b","stop", "stop", "c","stop")
ratings <- c(2,5,1, 1,3, 2) 

      

Vec contains information about the subcategories that have been scored, and stop is the end of each reviewer rating. Thus, I would like to organize the result into a data structure with this structure. Expected Result

enter image description here

I would really appreciate any help on this, because I've been working on this issue for much longer than it should take me to accept.

+3


source to share


4 answers


@alexis_laz provided what I think is the best answer:



vec <- c("a","b","c","stop", "a","b","stop", "stop", "c","stop")
ratings <- c(2,5,1, 1,3, 2) 

stops <- vec == "stop"
i = cumsum(stops)[!stops] + 1L
j = vec[!stops]
tapply(ratings, list(factor(i, 1:max(i)), factor(j)), identity) # although mean/sum work  
#      a  b  c
#[1,]  2  5  1
#[2,]  1  3 NA
#[3,] NA NA NA
#[4,] NA NA  2

      

+4


source


base R, but I am using a for loop ...



vec <- c("a","b","c","stop", "a","b","stop", "stop", "c","stop")
ratings <- c(2,5,1, 1,3, 2) 
categories <- unique(vec)[unique(vec)!="stop"]

row = 1
df = data.frame(lapply(categories, function(x){NA_integer_}))
colnames(df) <- categories
rating = 1

for(i in vec) {  
  if(i=='stop') {row <- row+1
  } else { df[row,i] <- ratings[[rating]]; rating <- rating+1}
}

      

+3


source


Here is one of the options

library(data.table)
library(reshape2)
d1 <- as.data.table(melt(split(vec, c(1, head(cumsum(vec == "stop")+1, 
        -1)))))[value != 'stop', ratings := ratings      
        ][value != 'stop'][, value := as.character(value)][, L1 := as.integer(L1)]


dcast( d1[CJ(value = value, L1 = seq_len(max(L1)), unique = TRUE), on = .(value, L1)], 
           L1 ~value, value.var = 'ratings')[, L1 := NULL][]
#    a  b  c
#1:  2  5  1
#2:  1  3 NA
#3: NA NA NA
#4: NA NA  2

      

+2


source


Using basic R functions and rbind.fill

from plyr

or rbindlist

from data.table

to create the final object, we can do

# convert vec into a list, split by "stop", dropping final element
temp <- head(strsplit(readLines(textConnection(paste(gsub("stop", "\n", vec, fixed=TRUE),
                                                     collapse=" "))), split=" "), -1)
# remove empty strings, but maintain empty list elements
temp <- lapply(temp, function(x) x[nchar(x) > 0])
# match up appropriate names to the individual elements in the list with setNames
# convert vectors to single row data.frames
temp <- Map(function(x, y) setNames(as.data.frame.list(x), y),
            relist(ratings, skeleton = temp), temp)

# add silly data.frame (single row, single column) for any empty data.frames in list
temp <- lapply(temp, function(x) if(nrow(x) > 0) x else setNames(data.frame(NA), vec[1]))

      

Now you can create a single data.frame (data.table) with plyr

ordata.table

# with plyr, returns data.frame
library(plyr)
do.call(rbind.fill, temp)
   a  b  c
1  2  5  1
2  1  3 NA
3 NA NA NA
4 NA NA  2

# with data.table, returns data.table
 rbindlist(temp, fill=TRUE)
    a  b  c
1:  2  5  1
2:  1  3 NA
3: NA NA NA
4: NA NA  2

      


Note that the line before rbind

ing can be replaced with

temp[lengths(temp) == 0] <- replicate(sum(lengths(temp) == 0),
                                      setNames(data.frame(NA), vec[1]), simplify=FALSE)

      

where list items, which are empty data frames, are replaced using a subset instead of lapply

across the entire list.

+2


source







All Articles