x must be numeric while trying to create histogram in R - r

I am a newbie in R. I need to generate some graphs. I imported an excel file and need to create a histogram on one column. My importing code is-
file=read.xlsx('femalecommentcount.xlsx',1,header=FALSE)
col=file[2]
col looks like this (part) -
36961 1
36962 1
36963 7
36964 1
36965 2
36966 1
36967 1
36968 4
36969 1
36970 6
36971 3
36972 1
36973 6
36974 6
36975 2
36976 2
36977 8
36978 2
36979 1
36980 1
36981 1
the first column is the row number. I'm not sure how to remove this. The second column is my data that I want a histogram on. hist() function requires a vector, I'm not sure how exactly to convert.
If I just simple call -
hist(col)
it gives-
Error in hist.default(col) : 'x' must be numeric
I have tried few commands randomly from the internet, but they didn't work.
My eventual goal is to just generate a good histogram (and maybe other charts) on that column, to get a good understadning of the spread of my data.

It should be col=file[[2]] or col=file[, 2] --- solution given in comment
data import should be in correct way to avoid numeric issue

Related

Changing vector of 1-10 to vector of 1-3 using R

I am using R to analyze a survey. Several of the columns include numbers 1-10, depending on how survey respondents answered the respective questions. I'd like to change the 1-10 scale to a 1-3 scale. Is there a simple way to do this? I was writing a complicated set of for loops and if statements, but I feel like there must be a better way in R.
I'd like to change numbers 1-3 to 1; numbers 4 and 8 to 2; numbers 5-7 to 3, and numbers 9 and 10 to NA.
So in the snippet below, OriginalColumn would become NewColumn.
OriginalColumn=c(4,9,1,10,8,3,2,7,5,6)
NewColumn=c(2,NA,1,NA,2,1,1,3,3,3)
Is there an easy way to do this without a bunch of crazy for loops? Thanks!
You can do this using positional indexing:
> c(1,1,1,2,3,3,3,2,NA,NA)[OriginalColumn]
[1] 2 NA 1 NA 2 1 1 3 3 3
It is better than repeated/nested ifelse because it is vectorized (thus easier to read, write, and understand; and probably faster). In essence, you're creating a new vector that contains that new values for every value you want to replace. So, for values 1:3 you want 1, thus the first three elements of the vector are 1, and so forth. You then use your original vector to extract the new values based on the positions of the original values.
You could also try
library(car)
recode(OriginalColumn, '1:3=1; c(4,8)=2; 5:7=3; else=NA')
#[1] 2 NA 1 NA 2 1 1 3 3 3

Gnuplot: How do I skip columns in matrix input to plot?

I have data file of the form:
unimportant1 unimportant2 unimportant3 matrixdata[i]
1e4 2e5 3e2 1 2 3 4 5
2e3 1e1 7e3 5 4 3 2 1
... ... ... ...
2e3 1e4 4e2 4 4 4 4 4
So it has columnheaders (here "unimportant1" to "unimportant3") as the first row. I want gnuplot to ignore these first three unimportant columns columns so the data entries in exponential notation. I want gnuplot to plot the matrixdata as a matrix. So as if I did it like this:
#!/usr/bin/gnuplot -p
plot '-' matrix with image
1 2 3 4 5
5 4 3 2 1
...
4 4 4 4 4
e
How do I get gnuplot to ignore the first three columns and the header row and plot the rest as matrix image? For compatibility, I would prefere a gnuplot built-in to do that, but I could write a shell script and use the `plot '< ...' syntax preprocessing the data file.
Edit: So neuhaus' answer almost solved it. The only thing I'm missing is, how to ignore the first row (line) with the text header data. Every seems to expect numeric data and so the whole plot fails as it's not a matrix. I don't want to comment out the fist line, as I'm using the unimportant data sets for other 2D plots that, in turn, use the header data.
So how do I skip a row in a matrix plot that already uses every to skip columns?
When using matrix gnuplot must first parse the data file before it can skip rows and columns. Now, your first row evaluates to four invalid number, the second row has 8 number and I get an error that Matrix does not represent a grid.
If you don't want to comment out the first line or skip it with an external tool like < tail -n +2 matrix.dat, then you could change it to contain some dummy strings like
unimportant1 unimportant2 unimportant3 matrixdata[i] B C D E
1e4 2e5 3e2 1 2 3 4 5
2e3 1e1 7e3 5 4 3 2 1
... ... ... ...
2e3 1e4 4e2 4 4 4 4 4
Now your first row has as many entries as the other rows, and you can plot this file with
plot 'test.txt' matrix every ::3:1 with image
This still gives you a warning: matrix contains missing or undefined values, but you don't need to care.
I'm not familiar with matrix plots, but I got some sample data and
plot 'matrix.dat' matrix every ::3 with image
seems to do the trick.
You could probably use shell commands, for instance, the following skips the first six lines of a file:
plot '<tail -n +7 terrain0.dem' matrix with image

R - Modified mosaic plot from descr package

I have a dataframe dbwith 2 categorical variables: varA has 4 levels (0,1,2,3), varB has 2 levels (yes,no). varB has no values for the level 0 of varA:
id varA varB
1 2 yes
2 3 no
3 3 no
4 1 yes
5 0 NA
6 1 no
7 2 no
8 3 yes
9 3 yes
10 2 no
I created a contingency table using CrossTable from the descr package and then a mosaic plot with the plot function:
table <- CrossTable(db$varA,db$varB, missing.include=FALSE)
plot(table,xlab="varA",ylab="varB")
I obtained this plot:
I would like to eliminate the level 0 from the plot. I also would like to add 2 y-axis, one on the left of the plot with a scale from 0 to 1 and one on the right with a scale from 1 to 0.
Could you help me?
Well, that was annoying. There is no support for subsetting such a "CrossTable" object. If it were a well-behaved table-like object you would been able to just pass table[ , -1] to the plot function. instead you need to do the subetting before the data that is passed to CrossTable:
table <- with( na.omit(db), CrossTable( varA, varB, missing.include=TRUE))
plot(table, xlab="varA", ylab="varB")
BTW using the name table for a data-object is quite confusing to regular R users since the table function is one of our basic tools.
Personally I would avoid avoid using that CrossTable function since its output is so weird and not available for management with typical R functions. Yeah, I know it produces a SAS-like output, but R users grow to love the compact output of the table function and the many matrix operations that are available for working with table-objects. You may need to get your margin percentages by hand with prop.table.

Simple R (histogram) from counted csv file [duplicate]

This question already has answers here:
Creating a histogram using aggregated data
(4 answers)
Closed 9 years ago.
HI Guys I'm trying to plot a frequency graph of a simple 2d file
file:data.csv
terms,count
1,10
5,17
3,28
9,30
I want the first col(terms) to be the x-axis and the col(count) be the height/percentage.
I've tried this:
d<-read.csv(data.csv)
hist(d)
Error in hist.default(d) : 'x' must be numeric
dc<-table(d)
hist(dc) <-- wrong result.
The problem is that hist() needs a vector containing your objects as often as they are present in your data. Your are providing it a frequency table.
See this:
> df <- data.frame(obj = c(1,2,3,4,5), count = c(2,3,5,4,2))
> hist(df)
Error in hist.default(df) : 'x' must be numeric
> hist(rep(df$obj, df$count), breaks=0:5)
[img]
> rep(df$obj, df$count)
[1] 1 1 2 2 2 3 3 3 3 3 4 4 4 4 5 5
rep(a,n) repeats element by element the value of a n-times. Then you have the vector you need and you can hand it to hist().
d<-read.csv(text="terms,count
1,10
5,17
3,28
9,30")
hist(d) # No error ... but not the plot you wanted.
Your lack of quotes around data.csv could be the problem or if the the first line in the file is really file:data.csv, that could be another problem. It does appear, however, that you probably want barchart or barplot, since you have already done the aggregation of the counts.
To illustrate why barchart or barplot could have been use:
require(lattice)
# dividing by total "counts" to get the fractional values
barchart(count/sum(d$count)~factor(terms), data=d)

filtering large data sets to exclude an identical element across all columns

I am a relatively new R user, and most of the complex coding (and packages) looks like Greek to me. It has been a long time since I used a programming language (Java/Perl) and I have only used R for very simple manipulations in the past (basic loading data from file, subsetting, ANOVA/T-Test). However, I am working on a project where I had no control over the data layout and the data file is very lengthy.
In my data, I have 172 rows which feature the Participant to a survey and 158 columns, each which represents the question number. The answers for each are 1-5. The raw data includes the number "99" to indicate that a question was not answered. I need to exclude any questions where a Participant did not answer without excluding the entire participant.
Part Q001 Q002 Q003 Q004
1 2 4 99 2
2 3 99 1 3
3 4 4 2 5
4 99 1 3 2
5 1 3 4 2
In the past I have used the subset feature to filter my data
data.filter <- subset(data, Q001 != 99)
Which works fine when I am working with sets where all my answers are contained in one column. Then this would just delete the whole row where the answer was not available.
However, with the answers in this set spread across 158 columns, if I subset out 99 in column 1 (Q001), I also filter out that entire Participant.
I'd like to know if there is a way to filter/subset the data such that my large data set would end up having 'blanks' when the "99" occured so that these 99's would not inflate or otherwise interfere with the statistics I run of the rest of the numbers. I need to be able to calculate means per question and run ANOVAs and T-Tests on various questions.
Resp Q001 Q002 Q003 Q004
1 2 4 2
2 3 1 3
3 4 4 2 5
4 1 3 2
5 1 3 4 2
Is this possible to do in R? I've tried to filter it before submitting to R, but it won't read the data file in when I have blanks, and I'd like to be able to use the whole data set without creating a subset for each question (which I will do if I have to... it's just time consuming if there is a better code or package to use)
Any assistance would be greatly appreciated!
You could replace the "99" by "NA" and the calculate the colMeans omitting NAs:
df <- replicate(20, sample(c(1,2,3,99), 4))
colMeans(df) # nono
dfc <- df
dfc[dfc == 99] <- NA
colMeans(dfc, na.rm = TRUE)
You can also indicate which values are NA's when you read your data base. For your particular case:
mydata <- read.table('dat_base', na.strings = "99")

Resources