R ifelse()计算条件并返回匹配

时间:2015-07-09 18:33:15

标签: r dplyr

我有一个数据框

countryname <- c("Viet Nam", "Viet Nam", "Viet Nam", "Viet Nam", "Viet Nam")
year <- c(1974, 1975, 1976, 1977,1978)

df <- data.frame(countryname, year)

这是一个长国的年份格式。

我想创建一个可以根据观察年份标准化国家名称的功能。我创建了一个能够从数据框cnames拉出并标准化名称的函数,但这仅适用于横截面,并且如果国家/地区名称不随时间变化。

country <- c("Vietnam, North", "Vietnam, N.", "Vietnam North", "Viet Nam", "Democratic Republic Of Vietnam")
standardize <- c("Vietnam, Democratic Republic of", "Vietnam, Democratic Republic of", "Vietnam, Democratic Republic of", "Vietnam, Democratic Republic of", "Vietnam, Democratic Republic of")
panel <- c("Vietnam", "Vietnam","Vietnam","Vietnam","Vietnam")
time <- c(1976,1976,1976,1976,1976)

cnames <- data.frame(country, standardize, panel, time)

标准化的功能是

country_name <- function(x) {
   return(cnames[match(x,cnames$country),]$standardize)
}

但是,正如您所看到的,这并未考虑到国家/地区名称随时间的变化。我尝试了很多不同的东西,而我最接近的就是这个功能。

country_panel <- function(x, y) {

  ifelse(cnames$time < y, 
    return(cnames[match(x, cnames$country),]$panel),
    return(cnames[match(x, cnames$country),]$standardize)
  )
}

我使用dplyr链来引入数据框,然后使用mutate创建一个新变量,理想情况下可以捕获国家/地区名称的差异。

d1 <- df %>%
    mutate(new_name = country_panel(countryname, year))

我发现的问题是该函数仅将y函数中的country_panel评估为单个对象而不是向量。如果我输入一个大于或小于cnames$time的整数,它会正确计算,但会传递每一行的值。

如何让此功能评估每个cnames$countrycnames$timedf$year的关系并返回正确的cnames$panelcnames$standardize

感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

d1
#   countryname year                        new_name
# 1    Viet Nam 1974 Vietnam, Democratic Republic of
# 2    Viet Nam 1975 Vietnam, Democratic Republic of
# 3    Viet Nam 1976 Vietnam, Democratic Republic of
# 4    Viet Nam 1977                         Vietnam
# 5    Viet Nam 1978                         Vietnam

您需要做的就是确保在定义数据框时将其设置为stringsAsFactors=F,即(df <- data.frame(countryname, year, stringsAsFactors=F))。并取出return命令:

country_panel <- function(x, y) {
  ifelse(cnames$time < y, 
    cnames[match(x, cnames$country),]$panel,
    cnames[match(x, cnames$country),]$standardize
  )
}

背后的原因是return一旦被调用就会停止其​​轨道中的功能。因此,您的数据框将由单个值输出填充。这就是为什么他们都是一样的。

答案 1 :(得分:0)

您可以根据年份和国家/地区名称加入表格:

left_join(df, cnames, by = c("countryname" = "country", "year" = "time"))

  countryname year                     standardize   panel
1    Viet Nam 1974                            <NA>    <NA>
2    Viet Nam 1975                            <NA>    <NA>
3    Viet Nam 1976 Vietnam, Democratic Republic of Vietnam
4    Viet Nam 1977                            <NA>    <NA>
5    Viet Nam 1978                            <NA>    <NA>