Related
I have a data.frame fish.test0 for which I want to grep specific variables (in varlist) matching the group column to create a sub-data.frame that will undergo a statistical test. The results of the test is saved in tests.res.t. I want to loop the varlist so that I get one results for each input in varlist
Script:
varlist <- c("Abiotrophia","Alphatorquevirus")
for (i in varlist) {
fish.test <- fish.test0[grep("i",fish.test0$group),]
column <- c("ACDC")
tests <- list()
dat_test <- sapply( column, function(colx)
lapply( unique(fish.test$Merge), function(x)
fisher.test( data.frame(
a=c(( fish.test[ which(fish.test$Merge %in% x)[2],"Present"] -
fish.test[ which(fish.test$Merge %in% x)[2], colx] ),fish.test[ which(fish.test$Merge %in% x)[2], colx]
),
b=c(( fish.test[ which(fish.test$Merge %in% x)[1],"NotPresent"] -
fish.test[ which(fish.test$Merge %in% x)[1], colx] ), fish.test[ which(fish.test$Merge %in% x)[1], colx]))) #,alternative = "greater"
) )
rownames(dat_test) <- unique(fish.test$Merge )
colnames(dat_test) <- column
tests.res <- sapply(dat_test[1:dim(dat_test)[1],1], function(x) {
c(x$estimate[1],
x$estimate[2],
ci.lower = x$conf.int[1],
ci.upper = x$conf.int[2],
p.value = x$p.value)
})
tests.res.t <- as.data.frame(t(tests.res))
}
test-data:
fish.test0 <- structure(list(Present = c(4L, 4L, 9L, 9L, 57L, 57L, 146L, 146L,
91L, 91L, 26L, 26L, 6L, 6L, 12L, 12L, 33L, 33L, 10L, 10L, 66L,
66L, 4L, 4L, 4L, 4L, 9L, 9L, 18L, 18L, 19L, 19L, 51L, 51L, 50L,
50L, 12L, 12L, 7L, 7L, 14L, 14L, 27L, 27L, 9L, 9L, 5L, 5L, 6L,
6L, 22L, 22L, 3L, 3L, 14L, 14L, 4L, 4L, 15L, 15L, 6L, 6L, 8L,
8L, 4L, 4L), NotPresent = c(11L, 11L, 44L, 44L, 126L, 126L, 532L,
532L, 382L, 382L, 97L, 97L, 14L, 14L, 43L, 43L, 85L, 85L, 41L,
41L, 336L, 336L, 19L, 19L, 27L, 27L, 67L, 67L, 108L, 108L, 81L,
81L, 240L, 240L, 258L, 258L, 47L, 47L, 31L, 31L, 82L, 82L, 110L,
110L, 63L, 63L, 178L, 178L, 672L, 672L, 451L, 451L, 120L, 120L,
104L, 104L, 47L, 47L, 387L, 387L, 94L, 94L, 300L, 300L, 133L,
133L), group = c("G__Abiotrophia_NotPresent_Anus", "G__Abiotrophia_Present_Anus",
"G__Abiotrophia_NotPresent_Bile duct", "G__Abiotrophia_Present_Bile duct",
"G__Abiotrophia_NotPresent_Bone/Soft tissue", "G__Abiotrophia_Present_Bone/Soft tissue",
"G__Abiotrophia_NotPresent_Breast", "G__Abiotrophia_Present_Breast",
"G__Abiotrophia_NotPresent_Colorectum", "G__Abiotrophia_Present_Colorectum",
"G__Abiotrophia_NotPresent_Esophagus", "G__Abiotrophia_Present_Esophagus",
"G__Abiotrophia_NotPresent_Gallbladder", "G__Abiotrophia_Present_Gallbladder",
"G__Abiotrophia_NotPresent_Head and neck", "G__Abiotrophia_Present_Head and neck",
"G__Abiotrophia_NotPresent_Kidney", "G__Abiotrophia_Present_Kidney",
"G__Abiotrophia_NotPresent_Liver", "G__Abiotrophia_Present_Liver",
"G__Abiotrophia_NotPresent_Lung", "G__Abiotrophia_Present_Lung",
"G__Abiotrophia_NotPresent_Lymphoid tissue", "G__Abiotrophia_Present_Lymphoid tissue",
"G__Abiotrophia_NotPresent_Mesothelium", "G__Abiotrophia_Present_Mesothelium",
"G__Abiotrophia_NotPresent_Nervous system", "G__Abiotrophia_Present_Nervous system",
"G__Abiotrophia_NotPresent_Ovary", "G__Abiotrophia_Present_Ovary",
"G__Abiotrophia_NotPresent_Pancreas", "G__Abiotrophia_Present_Pancreas",
"G__Abiotrophia_NotPresent_Prostate", "G__Abiotrophia_Present_Prostate",
"G__Abiotrophia_NotPresent_Skin", "G__Abiotrophia_Present_Skin",
"G__Abiotrophia_NotPresent_Small intestine", "G__Abiotrophia_Present_Small intestine",
"G__Abiotrophia_NotPresent_Stomach", "G__Abiotrophia_Present_Stomach",
"G__Abiotrophia_NotPresent_Unknown", "G__Abiotrophia_Present_Unknown",
"G__Abiotrophia_NotPresent_Urothelial tract", "G__Abiotrophia_Present_Urothelial tract",
"G__Abiotrophia_NotPresent_Uterus", "G__Abiotrophia_Present_Uterus",
"G__Alphatorquevirus_NotPresent_Bone/Soft tissue", "G__Alphatorquevirus_Present_Bone/Soft tissue",
"G__Alphatorquevirus_NotPresent_Breast", "G__Alphatorquevirus_Present_Breast",
"G__Alphatorquevirus_NotPresent_Colorectum", "G__Alphatorquevirus_Present_Colorectum",
"G__Alphatorquevirus_NotPresent_Esophagus", "G__Alphatorquevirus_Present_Esophagus",
"G__Alphatorquevirus_NotPresent_Kidney", "G__Alphatorquevirus_Present_Kidney",
"G__Alphatorquevirus_NotPresent_Liver", "G__Alphatorquevirus_Present_Liver",
"G__Alphatorquevirus_NotPresent_Lung", "G__Alphatorquevirus_Present_Lung",
"G__Alphatorquevirus_NotPresent_Pancreas", "G__Alphatorquevirus_Present_Pancreas",
"G__Alphatorquevirus_NotPresent_Skin", "G__Alphatorquevirus_Present_Skin",
"G__Alphatorquevirus_NotPresent_Urothelial tract", "G__Alphatorquevirus_Present_Urothelial tract"
), ABCD = c(3L, 2L, 17L, 6L, 34L, 18L, 240L, 53L, 321L, 73L,
87L, 25L, 6L, 3L, 20L, 8L, 15L, 7L, 19L, 4L, 265L, 42L, 6L, 1L,
4L, 2L, 22L, 4L, 70L, 13L, 54L, 12L, 116L, 33L, 58L, 11L, 6L,
2L, 26L, 6L, 42L, 8L, 74L, 18L, 19L, 3L, 52L, 0L, 288L, 5L, 377L,
17L, 110L, 2L, 19L, 3L, 21L, 2L, 298L, 9L, 60L, 6L, 68L, 1L,
89L, 3L), Total = c(15L, 15L, 53L, 53L, 183L, 183L, 678L, 678L,
473L, 473L, 123L, 123L, 20L, 20L, 55L, 55L, 118L, 118L, 51L,
51L, 402L, 402L, 23L, 23L, 31L, 31L, 76L, 76L, 126L, 126L, 100L,
100L, 291L, 291L, 308L, 308L, 59L, 59L, 38L, 38L, 96L, 96L, 137L,
137L, 72L, 72L, 183L, 183L, 678L, 678L, 473L, 473L, 123L, 123L,
118L, 118L, 51L, 51L, 402L, 402L, 100L, 100L, 308L, 308L, 137L,
137L), Merge = c("Abiotrophia_Anus", "Abiotrophia_Anus", "Abiotrophia_Bile duct",
"Abiotrophia_Bile duct", "Abiotrophia_Bone/Soft tissue", "Abiotrophia_Bone/Soft tissue",
"Abiotrophia_Breast", "Abiotrophia_Breast", "Abiotrophia_Colorectum",
"Abiotrophia_Colorectum", "Abiotrophia_Esophagus", "Abiotrophia_Esophagus",
"Abiotrophia_Gallbladder", "Abiotrophia_Gallbladder", "Abiotrophia_Head and neck",
"Abiotrophia_Head and neck", "Abiotrophia_Kidney", "Abiotrophia_Kidney",
"Abiotrophia_Liver", "Abiotrophia_Liver", "Abiotrophia_Lung",
"Abiotrophia_Lung", "Abiotrophia_Lymphoid tissue", "Abiotrophia_Lymphoid tissue",
"Abiotrophia_Mesothelium", "Abiotrophia_Mesothelium", "Abiotrophia_Nervous system",
"Abiotrophia_Nervous system", "Abiotrophia_Ovary", "Abiotrophia_Ovary",
"Abiotrophia_Pancreas", "Abiotrophia_Pancreas", "Abiotrophia_Prostate",
"Abiotrophia_Prostate", "Abiotrophia_Skin", "Abiotrophia_Skin",
"Abiotrophia_Small intestine", "Abiotrophia_Small intestine",
"Abiotrophia_Stomach", "Abiotrophia_Stomach", "Abiotrophia_Unknown",
"Abiotrophia_Unknown", "Abiotrophia_Urothelial tract", "Abiotrophia_Urothelial tract",
"Abiotrophia_Uterus", "Abiotrophia_Uterus", "Alphatorquevirus_Bone/Soft tissue",
"Alphatorquevirus_Bone/Soft tissue", "Alphatorquevirus_Breast",
"Alphatorquevirus_Breast", "Alphatorquevirus_Colorectum", "Alphatorquevirus_Colorectum",
"Alphatorquevirus_Esophagus", "Alphatorquevirus_Esophagus", "Alphatorquevirus_Kidney",
"Alphatorquevirus_Kidney", "Alphatorquevirus_Liver", "Alphatorquevirus_Liver",
"Alphatorquevirus_Lung", "Alphatorquevirus_Lung", "Alphatorquevirus_Pancreas",
"Alphatorquevirus_Pancreas", "Alphatorquevirus_Skin", "Alphatorquevirus_Skin",
"Alphatorquevirus_Urothelial tract", "Alphatorquevirus_Urothelial tract"
)), row.names = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 10L, 9L, 12L,
11L, 13L, 14L, 16L, 15L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 24L,
25L, 26L, 28L, 27L, 29L, 30L, 31L, 32L, 34L, 33L, 35L, 36L, 38L,
37L, 40L, 39L, 42L, 43L, 45L, 44L, 47L, 46L, 1011L, 1012L, 1014L,
1013L, 1015L, 1016L, 1017L, 1018L, 1019L, 1020L, 1022L, 1021L,
1023L, 1024L, 1026L, 1025L, 1027L, 1028L, 1029L, 1030L), class = "data.frame")
This is probably not an answer but it should help to improve you code. If I'm terribly wrong, I'll remove my answer right away. I have loeft out the test business which I don't understand, but your problem seems to be extraction.
The first thing is that you need to remove the quotation marks in your grep command, try:
varlist <- c("Abiotrophia","Alphatorquevirus")
for( i in varlist )
{
# extract rows which contain the variable
fish.test <- fish.test0[ grep( i, fish.test0$group ), ]
print( head( fish.test ) )
}
From what I understand, you need to define column and tests outside your loop. Does that give you more of what you want:
varlist <- c("Abiotrophia","Alphatorquevirus")
column <- "ACDC"
tests <- list()
for( i in 1 : length( varlist ) ) # index can be used later to fill the list
{
# extract rows which contain the variable
fish.test <- fish.test0[ grep( varlist[ i ], fish.test0$group ), ]
# add a column with your name of choice
fish.test <- cbind( fish.test, c( 1: length( fish.test$group ) ) )
colnames( fish.test )[ length( fish.test ) ] <- column
# write each result into your defined list
tests[[ i ]] <- fish.test
}
I have this dataframe
df <- structure(list(word = structure(c(1L, 12L, 23L, 34L, 43L, 44L,
45L, 46L, 47L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 13L,
14L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 24L, 25L, 26L, 27L,
28L, 29L, 30L, 31L, 32L, 33L, 35L, 36L, 37L, 38L, 39L, 40L, 41L,
42L), .Label = c("word1", "word10", "word11", "word12", "word13",
"word14", "word15", "word16", "word17", "word18", "word19", "word2",
"word20", "word21", "word22", "word23", "word24", "word25", "word26",
"word27", "word28", "word29", "word3", "word30", "word31", "word32",
"word33", "word34", "word35", "word36", "word37", "word38", "word39",
"word4", "word40", "word41", "word42", "word43", "word44", "word45",
"word46", "word47", "word5", "word6", "word7", "word8", "word9"
), class = "factor"), frq = c(1975L, 1665L, 1655L, 1469L, 1464L,
1451L, 1353L, 1309L, 1590L, 1545L, 1557L, 1556L, 1130L, 1153L,
1151L, 1150L, 1144L, 1141L, 1115L, 194L, 195L, 135L, 135L, 130L,
163L, 167L, 164L, 159L, 153L, 145L, 143L, 133L, 133L, 153L, 153L,
150L, 119L, 115L, 115L, 115L, 114L, 113L, 113L, 113L, 115L, 102L,
101L)), .Names = c("word", "frq"), class = "data.frame", row.names = c(NA,
-47L))
And I would like to create a word cloud based on the frequency.
In order to make this word cloud I use this lines of code:
library(wordcloud2)
wordcloud2(df, color = "random-light", backgroundColor = "green")
However an issue I face is that the word cloud doesn't have all the words. When I refer all words I mean these words with the lowest frequency.
Is there any scale in order to have all words in word cloud and the most frequency word be a little smaller in order to see all words?
As I can understand this happens because the highest frequencies have big difference with the others in the list
You should directly rescale your frequencies. You could for example do :
p_scaled = p^(1/n) with n sufficiently big so that even the words with the lowest frequencies would appear on the word cloud.
I have a dataframe in with 3 columns, two of which represent the i,j indices in a matrix. For each row of the dataframe, I would like to fill the corresponding i,j value in a matrix to 1.
Sharing the data and matrix below, which I think will make it easier to describe the problem:
data = structure(list(sale_id = c(0L, 1L, 2L, 2L, 3L, 3L, 4L, 4L, 5L,
5L, 5L, 5L, 5L, 5L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L,
8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 10L, 10L, 11L, 11L, 11L,
12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 14L, 15L, 16L, 16L,
17L, 17L, 17L, 17L, 17L, 18L, 18L, 19L, 19L, 20L, 20L, 21L, 22L,
22L, 23L, 23L, 23L, 24L, 24L, 25L, 25L, 26L, 26L, 27L, 27L, 28L,
28L, 29L, 30L, 30L, 30L, 30L, 30L, 30L, 30L, 31L, 31L, 32L, 32L,
33L, 33L, 33L, 33L, 33L, 33L, 34L, 34L), user_id = c(3219L, 144L,
2884L, 2884L, 2155L, 2155L, 2155L, 2155L, 2817L, 2817L, 2817L,
2817L, 2817L, 2817L, 144L, 144L, 2850L, 2850L, 2850L, 2850L,
2850L, 2850L, 2850L, 2850L, 2850L, 144L, 144L, 144L, 144L, 144L,
144L, 144L, 144L, 2817L, 2817L, 2075L, 2075L, 2546L, 2546L, 2546L,
2687L, 2687L, 2687L, 2687L, 2687L, 2687L, 2687L, 2687L, 170L,
2546L, 1963L, 144L, 144L, 1825L, 1825L, 1825L, 1825L, 1825L,
144L, 144L, 2155L, 2155L, 2546L, 2546L, 144L, 2155L, 2155L, 144L,
144L, 144L, 3182L, 3182L, 3343L, 3343L, 170L, 170L, 2155L, 2155L,
2793L, 2793L, 1564L, 2250L, 2250L, 2250L, 2250L, 2250L, 2250L,
2250L, 3083L, 3083L, 2075L, 2075L, 144L, 144L, 144L, 144L, 144L,
144L, 829L, 829L), item_id = c(174L, 10L, 179L, 162L, 171L, 182L,
179L, 185L, 199L, 179L, 195L, 174L, 162L, 198L, 144L, 69L, 57L,
47L, 83L, 80L, 10L, 117L, 14L, 90L, 88L, 186L, 167L, 192L, 142L,
162L, 173L, 151L, 134L, 191L, 166L, 118L, 128L, 98L, 95L, 119L,
130L, 154L, 155L, 181L, 120L, 118L, 77L, 120L, 101L, 31L, 139L,
10L, 30L, 182L, 179L, 139L, 173L, 171L, 80L, 39L, 26L, 69L, 163L,
151L, 175L, 150L, 148L, 121L, 147L, 88L, 183L, 177L, 132L, 167L,
176L, 172L, 57L, 78L, 98L, 99L, 118L, 102L, 141L, 97L, 99L, 79L,
32L, 17L, 16L, 30L, 66L, 54L, 57L, 91L, 81L, 39L, 92L, 123L,
87L, 62L)), .Names = c("sale_id", "user_id", "item_id"), row.names = c(NA,
100L), class = "data.frame")
M = matrix(0, nrow = max(data$user_id), ncol = max(data$item_id))
head(data, n = 6)
sale_id user_id item_id
1 0 3219 174
2 1 144 10
3 2 2884 179
4 2 2884 162
5 3 2155 171
6 3 2155 182
The i-column is user_id and the j-column is item_id. So for the first row, I would like for M[3219, 174] = 1, then I would like M[144, 10] = 1, etc. I would like to do this without a for-loop, which is too slow given the size of my matrix.
For reference, what I'm currently doing is:
for(i in 1:nrow(data)) {
M[data$user_id[i], data$item_id[i]] = 1
}
However, my problem scales quite large, and this is too slow for my problem. Any help is greatly appreciated! Thanks
EDIT: i tried something along the lines of:
apply(data, 1, FUN = function(x) M[x[2],x[3]] = 1)
but it didn't work as well as i would hope (takes even longer than the for-loop).
Try this:
M[cbind(data$user_id,data$item_id)] <- 1
I have a dataframe of the form
Region Name 3-15 4-15 5-15 ... 3-16
Name1 30 82 56 ... 32
Name2 65 23 38 ... 11
... ... ... ... ... ...
Name18 87 33 11 ... 51
The first column being the names of regions and the other columns being recorded events over time (monthly by column)
I'd like to plot the recorded monthly values over time with respect to their associated name. Specifically, a different line for each Named region with a differentiated colour. Any advice would be appreciated, a lot of the plotting functions for data frames seem to function on frames of a different format.
dput() data:
dataframe <- structure(list("LSOA Name" = c("Lancaster 001", "Lancaster 002",
"Lancaster 003", "Lancaster 004", "Lancaster 005", "Lancaster 006",
"Lancaster 008", "Lancaster 009", "Lancaster 010", "Lancaster 011",
"Lancaster 013", "Lancaster 014", "Lancaster 015", "Lancaster 016",
"Lancaster 017", "Lancaster 018", "Lancaster 019", "Lancaster 020"
), "3-15" = c(49L, 16L, 17L, 28L, 21L, 197L, 57L, 143L, 78L,
121L, 67L, 223L, 41L, 86L, 66L, 27L, 40L, 77L), "4-15" = c(63L,
11L, 26L, 29L, 19L, 203L, 69L, 154L, 82L, 125L, 62L, 198L, 44L,
99L, 64L, 26L, 42L, 99L), "5-15" = c(67L, 10L, 20L, 30L, 10L,
194L, 62L, 186L, 61L, 110L, 75L, 273L, 29L, 126L, 92L, 34L, 41L,
88L), "6-15" = c(58L, 8L, 18L, 36L, 29L, 198L, 62L, 167L, 83L,
110L, 59L, 254L, 26L, 99L, 73L, 17L, 30L, 109L), "7-15" = c(53L,
29L, 27L, 23L, 38L, 188L, 56L, 149L, 90L, 129L, 37L, 226L, 32L,
119L, 57L, 14L, 30L, 96L), "8-15" = c(44L, 9L, 25L, 28L, 29L,
237L, 69L, 171L, 78L, 108L, 45L, 261L, 22L, 103L, 68L, 33L, 35L,
108L), "9-15" = c(59L, 12L, 18L, 35L, 19L, 230L, 45L, 128L, 74L,
144L, 56L, 223L, 26L, 90L, 51L, 27L, 23L, 120L), "10-15" = c(45L,
26L, 31L, 23L, 25L, 195L, 53L, 155L, 74L, 120L, 58L, 276L, 38L,
92L, 72L, 25L, 40L, 123L), "11-15" = c(31L, 11L, 33L, 15L, 19L,
188L, 52L, 127L, 66L, 102L, 50L, 241L, 26L, 74L, 72L, 26L, 35L,
68L), "12-15" = c(34L, 22L, 21L, 22L, 17L, 205L, 80L, 150L, 73L,
109L, 50L, 228L, 29L, 57L, 59L, 14L, 45L, 93L), "1-16" = c(20L,
9L, 25L, 21L, 11L, 199L, 46L, 124L, 65L, 117L, 40L, 224L, 28L,
88L, 43L, 22L, 18L, 94L), "2-16" = c(54L, 11L, 29L, 20L, 11L,
164L, 44L, 117L, 70L, 85L, 46L, 192L, 23L, 89L, 50L, 27L, 29L,
86L), "3-16" = c(53L, 11L, 24L, 26L, 19L, 203L, 45L, 144L, 66L,
109L, 47L, 213L, 15L, 120L, 59L, 15L, 33L, 127L)), .Names = c("LSOA Name",
"3-15", "4-15", "5-15", "6-15", "7-15", "8-15", "9-15", "10-15",
"11-15", "12-15", "1-16", "2-16", "3-16"), row.names = c(NA,
-18L), class = "data.frame")
A typical way of plotting lines by groups in ggplot is to shift the data to long format, where one column identifies the group, and the other columns identify the x and y axis values.
This example shifts your data into long format with three columns: LSOAName, month_col, and values_col. It adds a day value onto the month-year, and converts that column to a date. Then it plots a line for each group.
I've renamed your dataframe d, because dataframe could be easily misinterpreted as the function data.frame().
# load libraries
library(magrittr)
library(dplyr)
library(tidyr)
library(ggplot2)
# rename dataframe so it doesn't look so much like the base function
d <- dataframe
# remove spaces in column names
names(d) <- gsub(" ", "", names(d))
# shift data from wide to long and then
# add a day value and convert day-month-year to date class
d %<>% gather(month_col, values_col, -LSOAName) %>%
mutate(month_col = as.Date(paste0("1-", month_col), "%d-%m-%y"))
# plot using ggplot2
ggplot(d, aes(x = month_col, y = values_col, colour = LSOAName)) +
geom_line()
Edit
%<>% is found in the magrittr package. It is a compound pipe assignment operator. While %>% returns the result of a pipeline, %<>% assigns the result back to the left side object.
Instead of writing
d <- d %>% [pipeline]
you can assign the results to d by writing
d %<>% [pipeline]
I have interesting data that is not uniform. A group of items are listed under the category name, but it is all in the same column. I need to add a column with the row corresponding to the item's category that it belongs to (then remove the category heading). The only way to distinguish a new category is determining whether the value under the year is empty.... My dputs should explain my issue more clearly.
Before:
structure(list(X = structure(c(13L, 1L, 19L, 16L, 5L, 17L, 11L,
8L, 2L, 10L, 4L, 6L, 18L, 15L, 21L, 12L, 14L, 9L, 3L, 20L, 7L
), .Label = c("-Burgers", "-Cameras", "-Shirts", "+Laptops",
"+Salads", "+TVs", "Caps", "Cell", "Clothes:", "Desktops", "Electronics",
"Flowers", "Food", "Garden Nomes", "Grills", "Hotdogs", "Nachoes",
"Outdoors:", "Pizza", "Shorts", "Swimming Gear"), class = "factor"),
X2000 = c(NA, 104L, 159L, 184L, 189L, 182L, NA, 49L, 28L,
46L, 34L, 43L, NA, 129L, 190L, 189L, 119L, NA, 45L, 80L,
80L), X2001 = c(NA, 147L, 192L, 164L, 174L, 196L, NA, 40L,
34L, 43L, 35L, 22L, NA, 114L, 130L, 120L, 145L, NA, 56L,
35L, 54L), X2002 = c(NA, 163L, 172L, 138L, 146L, 190L, NA,
38L, 40L, 21L, 22L, 33L, NA, 186L, 172L, 139L, 119L, NA,
88L, 78L, 91L), X2003 = c(NA, 125L, 152L, 182L, 148L, 125L,
NA, 36L, 44L, 34L, 27L, 50L, NA, 119L, 115L, 188L, 166L,
NA, 91L, 77L, 77L), X2004 = c(NA, 116L, 111L, 120L, 153L,
199L, NA, 49L, 48L, 43L, 37L, 32L, NA, 159L, 116L, 143L,
153L, NA, 18L, 53L, 51L)), .Names = c("X", "X2000", "X2001",
"X2002", "X2003", "X2004"), class = "data.frame", row.names = c(NA,
-21L))
After:
structure(list(X = structure(c(1L, 15L, 13L, 5L, 14L, 8L, 2L,
9L, 4L, 6L, 12L, 17L, 10L, 11L, 3L, 16L, 7L), .Label = c("-Burgers",
"-Cameras", "-Shirts", "+Laptops", "+Salads", "+TVs", "Caps",
"Cell", "Desktops", "Flowers", "Garden Nomes", "Grills", "Hotdogs",
"Nachoes", "Pizza", "Shorts", "Swimming Gear"), class = "factor"),
X.1 = structure(c(3L, 3L, 3L, 3L, 3L, 2L, 2L, 2L, 2L, 2L,
4L, 4L, 4L, 4L, 1L, 1L, 1L), .Label = c("Clothes:", "Electronics",
"Food", "Outdoors:"), class = "factor"), X2000 = c(104L,
159L, 184L, 189L, 182L, 49L, 28L, 46L, 34L, 43L, 129L, 190L,
189L, 119L, 45L, 80L, 80L), X2001 = c(147L, 192L, 164L, 174L,
196L, 40L, 34L, 43L, 35L, 22L, 114L, 130L, 120L, 145L, 56L,
35L, 54L), X2002 = c(163L, 172L, 138L, 146L, 190L, 38L, 40L,
21L, 22L, 33L, 186L, 172L, 139L, 119L, 88L, 78L, 91L), X2003 = c(125L,
152L, 182L, 148L, 125L, 36L, 44L, 34L, 27L, 50L, 119L, 115L,
188L, 166L, 91L, 77L, 77L), X2004 = c(116L, 111L, 120L, 153L,
199L, 49L, 48L, 43L, 37L, 32L, 159L, 116L, 143L, 153L, 18L,
53L, 51L)), .Names = c("X", "X.1", "X2000", "X2001", "X2002",
"X2003", "X2004"), class = "data.frame", row.names = c(NA, -17L
))
The items are arbitrarily have + or - signs...I need that to remain the same. Also, some category headers have : while others do not.
We create an index based on the 'NA' values in columns other than the 1st ('indx'). We split the dataset using the 'indx', remove the first row i.e. NA values from columns 2nd to the last, cbind with the 1st row, 1st column value, rearrange the columns and rbind.
indx <- cumsum(!rowSums(!is.na(df1[-1])))
res <- do.call(rbind,lapply(split(df1, indx), function(x)
cbind(x, X.1= x[1,1])[-1,c(1,7,2:6)]))
row.names(res) <- NULL
all.equal(res, out, check.attributes=FALSE)
#[1] TRUE
where 'out' is the dput output of the expected result
Update
If the columns have '' instead of NA,
indx <- cumsum(!rowSums(df1[-1]!=''))
and do the rest as above. Having said that, when we have '' in a numeric column, the class will be either factor or character based on whether you specify stringsAsFactors=FALSE or =TRUE in the read.table/read.csv. So, keeping the '' as such will get the output also a factor/character class. I would convert the columns to their correct class first which will also coerce the '' to NA, i.e.
df1[-1] <- lapply(df1[-1], function(x) as.numeric(as.character(x)))
The as.character is only needed if the columns are factor class.
Once, we have done the conversion, the first approach should work fine as well.