在数字向量中处理NA并使用变换

时间:2016-10-06 16:58:01

标签: r split transform

我提出了一种处理组合两列时遇到的问题的非常黑客的方法,但必须有更好/更有效的方法来完成我的工作。对R新手的任何建议都将不胜感激。

我有两个列,一个是代码,另一个是位置,不同年份。多年来数据不一致,例如,2004年的数据将代码和位置分开,而2012年的代码和位置在位置列中合并,使代码列为空。我首先想要将数据标准化多年,因此一个名为code_location的列将所有观察的代码和位置组合在一起,然后创建另外两列,一列包含代码,另一列包含位置。

以下是数据:

df <- read.table(text = c("
observation     year     code     location
1               2004     23-940   town no. 1
2               2004     23-941   town no. 2
3               2012     NA       23-940 town no. 1
4               2012     NA       23-941 town no. 2"), header = TRUE)

我尝试在下面的代码中使用transformpaste来合并这两列,但它

df_combined <- transform(df, code_location = paste(code, location, sep = " "))

它结合了2004年观测的代码和位置,但它包含了2012年观察代码栏中的NA。 (注意,代码和位置都是数字向量。我后来使用正则表达式,这变得很重要。我在代码列上尝试as.character以摆脱NA,但它后来搞砸了我的正则表达式。)

observation     year     code_location
1               2004     23-940 town no. 1
2               2004     23-941 town no. 2
3               2012     NA 23-940 town no. 1
4               2012     NA 23-941 town no. 2

为了解决这个问题,我创建了一个假人,告诉我哪些观察结果有NA而哪些没有,然后使用split来创建两个数据帧,做我需要得到的code_location,然后再次合并数据帧。这是我的代码:

df$cheat <- ifelse(is.na(df$code) == T, 0, 1) 
ls_df <- split(df, df$cheat)
df_code <- ls_df[[2]]
df_na <- ls_df[[1]]

df_code <- transform(df_code, code_location = paste(code, location, sep = " "))

df_combined <- rbind(df_code, df_na)

我得到以下输出,这是我想要的输出,但非常迂回。

observation     year     code_location
1               2004     23-940 town no. 1
2               2004     23-941 town no. 2
3               2012     23-940 town no. 1
4               2012     23-941 town no. 2

2 个答案:

答案 0 :(得分:1)

您可以使用ifelse功能:

transform(df, code_location = ifelse(is.na(code),
                                     as.character(location),
                                     paste(code, location)))

请注意df$location是一个因素,因此如果单独使用它,则需要将其转换为字符。

答案 1 :(得分:0)

示例中用于读取数据的代码不起作用,请使用dput()提供可用的示例数据。

我建议使用apply()解决您的问题:

as.data.frame(t(apply(df,1,function(row_tmp){
    if(is.na(row_tmp[3])){
        split_tmp <- strsplit(row_tmp[4]," ")[[1]]
        row_tmp[3] <- split_tmp[1]
        row_tmp[4] <- paste(split_tmp[-1], collapse = " ")
    }
    return(row_tmp)
})), stringsAsFactors= F)

如果在第3列中遇到NA,则apply函数遍历所有行并拆分最后一列。