我正在尝试使用ifelse
创建一个新变量,将两个data.frames
的数据组合在一起(类似于this问题,但没有因素)。
我的问题是,df1
以年度数据为特色,而df2
中的变量在时间上汇总:例如df1
有多个obs(1997,1998,...,2005),df2
只有一个范围(1900-2001)。
为了说明,2x2示例看起来像
df1$id <- c("2","20")
df1$year <- c("1960","1870")
df2$id <- df1$id
df2$styear <- c("1800","1900")
df2$endyear <- c("2001","1950")
我希望以这样的方式组合两者,以便匹配id(同时存在两个变量),此外,df1
中的年份在df2
的范围内。我尝试了以下
df1$new.var <- ifelse(df1$id==df2$id & df1$year>=df2$styear &
df1$year<df2$endyear,1,0)
理想情况下应分别返回1和0。
但我收到了警告信息:
1:在df1 $ id == df2 $ id中:较长的对象长度不是倍数 较短的物体长度
2:在df1 $ year&gt; = df2 $ styear:较长的对象长度不是a 多个较短的物体长度
3:在df1 $ year&lt; df2 $ endyear:较长的对象长度不是a 多个较短的物体长度
对于记录,'真实'df1
有500个障碍,df2
有14.我怎样才能使这个工作?
编辑:我意识到df2
中的某些障碍被重复,有多个句号,例如
id styear endyear
1 1800 1915
1 1950 2002
2 1912 1988
3 1817 2000
所以,我相信我需要的东西就像双重ifelse:
df1$new.var <- ifelse(df1$id==df2$id & df1$year>=df2$styear &
df1$year<df2$endyear | df1$year>=df2$styear &
df1$year<df2$endyear,1,0)
显然,这不起作用,但它是摆脱重复问题的一种方法。
例如,如果id=1
中df1$year=1801
,它将通过第一年范围测试(1801年是1800-1915之间),但是第二年测试失败(1801不是1950年至2002年之间) ),所以它只编码一次,没有添加额外的行(目前重复项添加额外的行)。
答案 0 :(得分:1)
df1$id <- c("2","20")
df1$year <- c("1960","1870")
df2$id <- df1$id
df2$styear <- c("1800","1900")
df2$endyear <- c("2001","1950")
library(dplyr)
df3 <- left_join(df1,df2,by = "id") %>% filter(year <= endyear,year >= startyear)
我强烈建议使用dplyr软件包进行数据操作。
答案 1 :(得分:0)
以基地R:
df1 <- data.frame(id=c(2,20,22), year=c(1960,1870, 2016))
df2 <- data.frame(id=c(2,20,21), styear=c(1800,1900,2000), endyear=c(2001,1950,2016))
df1
id year
1 2 1960
2 20 1870
3 22 2016
df2
id styear endyear
1 2 1800 2001
2 20 1900 1950
3 21 2000 2016
df1 <- merge(df1, df2, by='id', all.x = TRUE)
df1$new.var <- !is.na(df1$styear) & df1$year>=df1$styear & df1$year< df1$endyear
df1 <- df1[c('id', 'year', 'new.var')]
df1
id year new.var
1 2 1960 TRUE
2 20 1870 FALSE
3 22 2016 FALSE
答案 2 :(得分:0)
好吧,我让它适合自己。要注意,它很复杂,可能包含一些冗余。在简要了解数据争用cheatsheet之后,假设您df1
和df2
具有相同的var
且df2
包含new.var
,可以做到以下几点:
library(dplyr)
#Join everything, all values and rows
df3 <- full_join(df1,df2,by="id")
#filter out obs those year is greater than endyear
df3 <- filter(df3,df3$year<=df3$endyear)
#same, the other way around
df3 <- filter(df3,df3$year>=df3$styear)
df3 <- distinct(df3) #remove duplicate rows (at least I had some)
据我所知,通过查看最终结果,此方法仅从正确的时间段中提取信息,同时将所有其他时间段放在df2
中。然后,这是与原始data.frame(df1
)合并并填写NA的问题:
df1 <- merge(df1,df3,by=(id),all.x=TRUE)
df1 <- distinct(df1) #just to make sure, I still had three
df1$new.var <- ifelse(is.na(df1$new.var),0,df1$new.var)
这就是我想要的。
答案 3 :(得分:0)
使用library(data.table)
setDT(df1); setDT(df2) # converting to data.table in place
df1[, new.var := df2[df1, on = .(id, styear <= year, endyear >= year),
.N > 0, by = .EACHI]$V1]
df1
# id year new.var
#1: 2 1960 TRUE
#2: 20 1870 FALSE
devel version(1.9.7 +)中的非等联接可以轻松有效地解决这个问题:
df2
以上联接在df1
(by = .EACHI
(.N
)的每一行中查找filterList (filterText) {
var updatedList = this.props.array;
return updatedList.filter(function(item){
var split = item.name.split(" ");
console.log(split, filterText);
return split === filterText;
});
}
中的匹配项,并检查匹配行数({{1}})。