我提出了一种处理组合两列时遇到的问题的非常黑客的方法,但必须有更好/更有效的方法来完成我的工作。对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)
我尝试在下面的代码中使用transform
和paste
来合并这两列,但它
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
答案 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函数遍历所有行并拆分最后一列。