I want to subtract the year in which the respondents were born (variables containing yrbrn) by the variable for year of the interview (inwyys) and save the results as new variables in the data frame.
Head of the data frame:
inwyys yrbrn2 yrbrn3 yrbrn4 yrbrn5 yrbrn6 yrbrn7 yrbrn8
1 2012 1949 1955 NA NA NA NA NA
2 2012 1983 1951 1956 1989 1995 2003 2005
3 2012 1946 1946 1978 NA NA NA NA
4 2013 NA NA NA NA NA NA NA
5 2013 1953 1959 1980 1985 1991 2008 2011
6 2013 1938 NA NA NA NA NA NA
Can someone help me with that?
Thank you very much!
This can be done by sub-setting (x[,-1]..take everything but not the first column, x[,1]..take the first column) your data and make the subtraction. With cbind you can bind the new result to the original data.
cbind(x, x[,-1] - x[,1])
# inwyys yrbrn2 yrbrn3 yrbrn4 yrbrn5 yrbrn6 yrbrn7 yrbrn8 yrbrn2 yrbrn3 yrbrn4 yrbrn5 yrbrn6 yrbrn7 yrbrn8
#1 2012 1949 1955 NA NA NA NA NA -63 -57 NA NA NA NA NA
#2 2012 1983 1951 1956 1989 1995 2003 2005 -29 -61 -56 -23 -17 -9 -7
#3 2012 1946 1946 1978 NA NA NA NA -66 -66 -34 NA NA NA NA
#4 2013 NA NA NA NA NA NA NA NA NA NA NA NA NA NA
#5 2013 1953 1959 1980 1985 1991 2008 2011 -60 -54 -33 -28 -22 -5 -2
#6 2013 1938 NA NA NA NA NA NA -75 NA NA NA NA NA NA
Data:
x <- read.table(header=TRUE, text=" inwyys yrbrn2 yrbrn3 yrbrn4 yrbrn5 yrbrn6 yrbrn7 yrbrn8
1 2012 1949 1955 NA NA NA NA NA
2 2012 1983 1951 1956 1989 1995 2003 2005
3 2012 1946 1946 1978 NA NA NA NA
4 2013 NA NA NA NA NA NA NA
5 2013 1953 1959 1980 1985 1991 2008 2011
6 2013 1938 NA NA NA NA NA NA")
I believe the following is what you are looking for
data$newvar1<-data$yrbrn2-data$inwyys
But replace "data" with the name of your data set. If you want to do it for each yrbrn column, just change "newvar1" to "newvar2" etc so you do not override your previous calculations
Related
I have a data set that contains a column with country names, it looks like this:
> xx
# A tibble: 139 × 5
Country `2012_value` `2013_value` `2014_value` `2015_value`
<chr> <dbl> <dbl> <dbl> <dbl>
1 Albania NA NA NA 35
2 Algeria 1 1 1 NA
3 Andorra NA NA NA 50
4 Antigua & Barbuda NA NA NA 98
5 Argentina NA NA NA 65
6 Armenia NA 44 46 46.5
7 Ascension NA NA NA 100
8 Austria NA NA NA 98
9 Azerbaijan NA NA 49 50
10 Bahamas NA NA NA 95
I would like to change the names of the countries according to a table I have:
> print(itu_emi_countries, n = 30)
# A tibble: 215 × 2
`ITU Name` `EMI Name`
<chr> <chr>
1 Afghanistan Afghanistan
2 Albania Albania
3 Algeria Algeria
4 American Samoa American Samoa
5 Andorra Andorra
6 Angola Angola
7 Antigua & Barbuda Antigua
8 Argentina Argentina
9 Armenia Armenia
10 Aruba Aruba
11 Australia Australia
12 Austria Austria
13 Azerbaijan Azerbaijan
14 Bahamas Bahamas
15 Bahrain Bahrain
16 Bangladesh Bangladesh
17 Barbados Barbados
18 Belarus Belarus
19 Belgium Belgium
20 Belize Belize
21 Benin Benin
22 Bermuda Bermuda
23 Bhutan Bhutan
24 Bolivia Bolivia
25 Bosnia and Herzegovina Bosnia-Herzegovina
26 Botswana Botswana
27 Brazil Brazil
28 Brunei Darussalam Brunei
29 Bulgaria Bulgaria
30 Burkina Faso Burkina Faso
# … with 185 more rows
The country names are written as in the first column, and I want to change them to the second column. How can I do this?
A simple rename and left_join does the trick:
library(tidyverse)
itu_emi_countries <- itu_emi_countries %>%
rename(Country = `ITU Name`)
left_join(xx, itu_emi_countries, by = "Country")
With dplyr, you could use recode() and pass a named vector indicating the relations between the old and new names.
library(dplyr)
xx %>%
mutate(Country = recode(Country, !!!tibble::deframe(itu_emi_countries)))
This question already has answers here:
Replacing NAs with latest non-NA value
(21 answers)
Closed 3 years ago.
I have a dataframe like this:
ID year fcmstat secmstat mstat
138 4 1998 NA NA 1
139 4 1999 NA NA 1
140 4 2000 NA NA 1
141 4 2001 NA NA 1
142 4 2002 NA NA 1
143 4 2003 2 NA 2
144 4 2004 NA NA NA
145 4 2005 NA NA NA
146 4 2006 NA 3 3
147 4 2007 NA NA NA
375 19 2001 NA NA 2
376 19 2002 6 NA 6
377 19 2003 NA NA NA
378 19 2004 NA 5 5
379 19 2005 NA NA NA
380 19 2006 NA NA 1
fcmstat: type of first marital status change
secmstat: type of second marital status change
first marital status, for ID 4(19), fsmstat was changed in 2003(2002) and second marital status secmstat was changed in 2006(2004). So, for ID 4, in 2004 and 2005 marital status was same as fcmstat of 2003 and for ID 19, 2003's mstat should be same as fcmstat of 2002.
I want to fill in t he last column as follows:
ID year fcmstat secmstat mstat
138 4 1998 NA NA 1
139 4 1999 NA NA 1
140 4 2000 NA NA 1
141 4 2001 NA NA 1
142 4 2002 NA NA 1
143 4 2003 2 NA 2
144 4 2004 NA NA 2
145 4 2005 NA NA 2
146 4 2006 NA 3 3
147 4 2007 NA NA NA
375 19 2001 NA NA 2
376 19 2002 6 NA 6
377 19 2003 NA NA 6
378 19 2004 NA 5 5
379 19 2005 NA NA NA
380 19 2006 NA NA 1
Also, before any first change, the mstatshould be same as before. Consider the following case.
ID year fcmstat secmstat mstat
1171 61 1978 NA NA 0
1172 61 1979 NA NA 0
1173 61 1980 NA NA 0
1174 61 1981 NA NA 0
1175 61 1982 NA NA 0
1176 61 1983 NA NA NA
1177 61 1984 NA NA NA
1178 61 1985 1 NA 1
1179 61 1986 NA NA 1
1180 61 1987 NA NA 1
the first change was in 1985. So, the missing mstat in 1984 and 1983 should be same as mstat of 1982. SO for this case, my desired output is:
ID year fcmstat secmstat mstat
1171 61 1978 NA NA 0
1172 61 1979 NA NA 0
1173 61 1980 NA NA 0
1174 61 1981 NA NA 0
1175 61 1982 NA NA 0
1176 61 1983 NA NA 0
1177 61 1984 NA NA 0
1178 61 1985 1 NA 1
1179 61 1986 NA NA 1
1180 61 1987 NA NA 1
As suggested by Schilker the code df$mstat_updated<-na.locf(df$mstat) gives the following:
ID year fcmstat secmstat mstat mstat_updated
138 4 1998 NA NA 1 1
139 4 1999 NA NA 1 1
140 4 2000 NA NA 1 1
141 4 2001 NA NA 1 1
142 4 2002 NA NA 1 1
143 4 2003 2 NA 2 2
144 4 2004 NA NA NA 2
145 4 2005 NA NA NA 2
146 4 2006 NA 3 3 3
147 4 2007 NA NA NA 3
148 4 2008 NA NA NA 3
However, I do want to fill in mstat for 2004 and 2005 but not in 2007 and 2008. I want to fill in NA's only between first marstat change, fcmstat and second marstat, secmstat change.
As I mentioned in my comment this a duplicate of here
library(zoo)
df<-data.frame(ID=c('4','4','4','4'),
year=c(2003,2004,2005,2006),
mstat=c(2,NA,NA,3))
df$mstat<-na.locf(df$mstat)
So I have a few really big data sets that I want to merge in the manner that I indicated below. And I tried to do it like this:
setwd(..)
myfiles = list.files(pattern="*.dta")
dflist <- lapply(myfiles, read.dta13)
merged.data.frame = Reduce(function(...) merge(..., all=T), dflist)
However, I keep running out of memory...
Is there another way I can accomplish this without running out of memory?
What the dataframes look like, and what I want the merged product to be:
Dataframe 1
Country Year Sector ID Var 1
Austria 2001 Construction lp 22
Austria 2001 Construction fp 23
Austria 2001 Manufact lp 12
Austria 2001 Manufact fp 43
Austria 2002 Construction lp 55
Austria 2002 Construction fp 34
Austria 2002 Manufact lp 16
Austria 2002 Manufact fp 76
Dataframe 2
Country Year Sector Type Var1 Var2
Austria 2001 Construction A 23 5
Austria 2001 Construction B 34 5
Austria 2001 Manufact A 98 4
Austria 2001 Manufact B 48 3
Austria 2002 Construction A 43 9
Austria 2002 Construction B 23 7
Austria 2002 Manufact A 65 6
Austria 2002 Manufact B 45 6
Dataframe 3
Country Year Sector Var3
Austria 2001 Construction 123
Austria 2001 Acco 345
Austria 2001 Manufact 234
Austria 2001 Prod 466
Austria 2002 Construction 785
Austria 2002 Acco 789
Austria 2002 Manufact 678
Austria 2002 Prod 899
Merged:
Country Year Sector ID Type Var1 Var2 Var3
Austria 2001 Construction lp NA 22 NA NA
Austria 2001 Construction fp NA 23 NA NA
Austria 2001 Construction NA A 23 5 NA
Austria 2001 Construction NA B 34 5 NA
Austria 2001 Construction NA NA NA NA 123
Austria 2001 Manufact lp NA 12 NA NA
Austria 2001 Manufact fp NA 43 NA NA
Austria 2001 Manufact NA A 98 4 NA
Austria 2001 Manufact NA B 48 3 NA
Austria 2001 Manufact NA NA NA NA 234
Austria 2001 Acco NA NA NA NA 345
Austria 2001 Prod NA NA NA NA 466
.... 2002 ....
and so on.
I have a df with states that I am trying to add lat, long values for each state so I can plot percent values for each state on a map. When I use merge I get either and empty df if I don't use
all=TRUE
Or I get missing data for either my lat, long values of my data itself depending on which I make x or y
Code to load my df and add column header
fileURL <- c("https://drive.google.com/open?id=0B-jAX5hT2D3hNnVtLVhROENKRGs")
suppressMessages(require(data.table))
ge.planted <- fread(fileURL, na.strings = "NA")
colnames(ge.planted) <- c("region", "type", "crop", "2000", "2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2015")
Code to get state names with lat, long values for the center of each state
snames <- data.frame(region=tolower(state.name), long=state.center$x, lat=state.center$y)
When I merge the two df using:
snames <- merge(ge.planted, snames, by="region")
I get
[1] region long lat type crop 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010
[17] 2011 2012 2013 2014 2015
Or if I use
snames <- merge( ge.planted, snames, by="region", all=TRUE)
And I get my values but no lat, long
region type crop 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013
1: Alabama Insect-resistant (Bt) only Cotton - - - - - 10 10 10 18 13 11 18 17 12
2: Alabama Herbicide-tolerant only Cotton - - - - - 28 25 25 15 18 7 4 11 4
3: Alabama Stacked gene varieties Cotton - - - - - 54 60 60 65 60 76 75 70 82
4: Alabama All GE varieties Cotton - - - - - 92 95 95 98 91 94 97 98 98
5: Arkansas Herbicide-tolerant only Soybean 43 60 68 84 92 92 92 92 94 94 96 95 94 97
6: Arkansas All GE varieties Soybean 43 60 68 84 92 92 92 92 94 94 96 95 94 97
2014 2015 long lat
1: 9 4 NA NA
2: 6 3 NA NA
3: 83 90 NA NA
4: 98 97 NA NA
5: 99 97 NA NA
6: 99 97 NA NA
And finally with
snames <- merge(snames, ge.planted, by="region", all=TRUE)
I get lat, long but no values
region long lat type crop 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015
1 alabama -87 33 <NA> <NA> <NA> <NA> <NA> <NA> <NA> NA NA NA NA NA NA NA NA NA NA NA
2 alaska -127 49 <NA> <NA> <NA> <NA> <NA> <NA> <NA> NA NA NA NA NA NA NA NA NA NA NA
3 arizona -112 34 <NA> <NA> <NA> <NA> <NA> <NA> <NA> NA NA NA NA NA NA NA NA NA NA NA
4 arkansas -92 35 <NA> <NA> <NA> <NA> <NA> <NA> <NA> NA NA NA NA NA NA NA NA NA NA NA
5 california -120 37 <NA> <NA> <NA> <NA> <NA> <NA> <NA> NA NA NA NA NA NA NA NA NA NA NA
6 colorado -106 39 <NA> <NA> <NA> <NA> <NA> <NA> <NA> NA NA NA NA NA NA NA NA NA NA NA
From best I can tell instead of merging the files based on 'region' it is appending the 'y' value on to the end of the data frame.
The problem is that you used tolower(), so that region names in one frame are different to the other (ge.planted has caps, snames does not). So merge will not recognize region names as equivalent. Delete the tolower() call, and it should work.
I am struggling with the following problem:
The dataframe below contains the development of a value over time for various ids. What i try to get is the increase/decrease of these values based on a the value in a year when event occurred. Several events can occur within one id, so a new event becomes the new baseline year for the id.
To make things clearer, I also add the outcome I want below
What i have
id value year event
a 100 1950 NA
a 101 1951 NA
a 102 1952 NA
a 103 1953 NA
a 104 1954 NA
a 105 1955 X
a 106 1956 NA
a 107 1957 NA
a 108 1958 NA
a 107 1959 Y
a 106 1960 NA
a 105 1961 NA
a 104.8 1962 NA
a 104.2 1963 NA
b 70 1970 NA
b 75 1971 NA
b 80 1972 NA
b 85 1973 NA
b 90 1974 NA
b 60 1975 Z
b 59 1976 NA
b 58 1977 NA
b 57 1978 NA
b 56 1979 NA
b 55 1980 W
b 54 1981 NA
b 53 1982 NA
b 52 1983 NA
b 51 1984 NA
What I am looking for
id value year event index growth
a 100 1950 NA 0
a 101 1951 NA 0
a 102 1952 NA 0
a 103 1953 NA 0
a 104 1954 NA 0
a 105 1955 X 1 1
a 106 1956 NA 2 1.00952381
a 107 1957 NA 3 1.019047619
a 108 1958 NA 4 1.028571429
a 107 1959 Y 1 1 #new baseline year
a 106 1960 NA 2 0.990654206
a 105 1961 NA 3 0.981308411
a 104.8 1962 NA 4 0.979439252
a 104.2 1963 NA 5 0.973831776
b 70 1970 NA 6
b 75 1971 NA 7
b 80 1972 NA 8
b 85 1973 NA 9
b 90 1974 NA 10
b 60 1975 Z 1 1
b 59 1976 NA 2 0.983333333
b 58 1977 NA 3 0.966666667
b 57 1978 NA 4 0.95
b 56 1979 NA 5 0.933333333
b 55 1980 W 1 1 #new baseline year
b 54 1981 NA 2 0.981818182
b 53 1982 NA 3 0.963636364
b 52 1983 NA 4 0.945454545
b 51 1984 NA 5 0.927272727
What I tried
This and this post were quite helpful and I managed to create differences between the years, however, I fail to reset the base year (index) when there is a new event. Furthermore, I am doubtful whether my approach is indeed the most efficient/elegant one. Seems a bit clumsy to me...
x <- ddply(x, .(id), transform, year.min=min(year[!is.na(event)])) #identifies first event year
x1 <- ddply(x[x$year>=x$year.min,], .(id), transform, index=seq_along(id)) #creates counter years following first event; prior years are removed
x1 <- x1[order(x1$id, x1$year),] #sort
x1 <- ddply(x1, .(id), transform, growth=100*(value/value[1])) #calculate difference, however, based on first event year; this is wrong.
library(Interact) #i then merge the df with the years prior to first event which have been removed in the begining
x$id.year <- interaction(x$id,x$year)
x1$id.year <- interaction(x1$id,x1$year)
x$index <- x$growth <- NA
y <- rbind(x[x$year<x$year.min,],x1)
y <- y[order(y$id,y$year),]
Many thanks for any advice.
# Create a tag to indicate the start of each new event by id or
# when id changes
dat$tag <- with(dat, ave(as.character(event), as.character(id),
FUN=function(i) cumsum(!is.na(i))))
# Calculate the growth by id and tag
# this will also produce results for each id before an event has happened
dat$growth <- with(dat, ave(value, tag, id, FUN=function(i) i/i[1] ))
# remove growth prior to an event (this will be when tag equals zero as no
# event have occurred)
dat$growth[dat$tag==0] <- NA
Here is a solution with dplyr.
ana <- group_by(mydf, id) %>%
do(na.locf(., na.rm = FALSE)) %>%
mutate(value = as.numeric(value)) %>%
group_by(id, event) %>%
mutate(growth = value/value[1]) %>%
mutate(index = row_number(event))
ana$growth[is.na(ana$event)] <- 0
id value year event growth index
1 a 100.0 1950 NA 0.0000000 1
2 a 101.0 1951 NA 0.0000000 2
3 a 102.0 1952 NA 0.0000000 3
4 a 103.0 1953 NA 0.0000000 4
5 a 104.0 1954 NA 0.0000000 5
6 a 105.0 1955 X 1.0000000 1
7 a 106.0 1956 X 1.0095238 2
8 a 107.0 1957 X 1.0190476 3
9 a 108.0 1958 X 1.0285714 4
10 a 107.0 1959 Y 1.0000000 1
11 a 106.0 1960 Y 0.9906542 2
12 a 105.0 1961 Y 0.9813084 3
13 a 104.8 1962 Y 0.9794393 4
14 a 104.2 1963 Y 0.9738318 5
15 b 70.0 1970 NA 0.0000000 1
16 b 75.0 1971 NA 0.0000000 2
17 b 80.0 1972 NA 0.0000000 3
18 b 85.0 1973 NA 0.0000000 4
19 b 90.0 1974 NA 0.0000000 5
20 b 60.0 1975 Z 1.0000000 1
21 b 59.0 1976 Z 0.9833333 2
22 b 58.0 1977 Z 0.9666667 3
23 b 57.0 1978 Z 0.9500000 4
24 b 56.0 1979 Z 0.9333333 5
25 b 55.0 1980 W 1.0000000 1
26 b 54.0 1981 W 0.9818182 2
27 b 53.0 1982 W 0.9636364 3
28 b 52.0 1983 W 0.9454545 4
Try:
ddf$index=0
ddf$growth=0
baseline =0
r=1; start=FALSE
for(r in 1:nrow(ddf)){
if(is.na(ddf$event[r])){
if(start) {
ddf$index[r] = ddf$index[r-1]+1
ddf$growth[r] = ddf$value[r]/baseline
}
else {ddf$index[r] = 0;
}
}
else{
start=T
ddf$index[r] = 1
ddf$growth[r]=1
baseline = ddf$value[r]
}
}
ddf
id value year event index growth
1 a 100.0 1950 <NA> 0 0.0000000
2 a 101.0 1951 <NA> 0 0.0000000
3 a 102.0 1952 <NA> 0 0.0000000
4 a 103.0 1953 <NA> 0 0.0000000
5 a 104.0 1954 <NA> 0 0.0000000
6 a 105.0 1955 X 1 1.0000000
7 a 106.0 1956 <NA> 2 1.0095238
8 a 107.0 1957 <NA> 3 1.0190476
9 a 108.0 1958 <NA> 4 1.0285714
10 a 107.0 1959 Y 1 1.0000000
11 a 106.0 1960 <NA> 2 0.9906542
12 a 105.0 1961 <NA> 3 0.9813084
13 a 104.8 1962 <NA> 4 0.9794393
14 a 104.2 1963 <NA> 5 0.9738318
15 b 70.0 1970 <NA> 6 0.6542056
16 b 75.0 1971 <NA> 7 0.7009346
17 b 80.0 1972 <NA> 8 0.7476636
18 b 85.0 1973 <NA> 9 0.7943925
19 b 90.0 1974 <NA> 10 0.8411215
20 b 60.0 1975 Z 1 1.0000000
21 b 59.0 1976 <NA> 2 0.9833333
22 b 58.0 1977 <NA> 3 0.9666667
23 b 57.0 1978 <NA> 4 0.9500000
24 b 56.0 1979 <NA> 5 0.9333333
25 b 55.0 1980 W 1 1.0000000
26 b 54.0 1981 <NA> 2 0.9818182
27 b 53.0 1982 <NA> 3 0.9636364
28 b 52.0 1983 <NA> 4 0.9454545
29 b 51.0 1984 <NA> 5 0.9272727