我经常以excel电子表格的格式获取数据,如下所示:
Name1 Data
Data
Data
Name2 Data
Data
Data
....
当我将其读入R时,空白行将我们作为NA,然后我总是编写一些特殊代码来填充它,以便它看起来像:
Name1 Data
Name1 Data
Name1 Data
Name2 Data
Name2 Data
Name2 Data
....
通常情况下,我只是使用for循环来跟踪姓氏,每次看到NA我都填写它。下次当我在名称列中看到某些内容时,我会保存新名称和开始写那个。
我想知道是否有更漂亮的R矢量化版本?
谢谢!
答案 0 :(得分:4)
你可以尝试
indx <- !is.na(df$Col1)
df$Col1 <- df$Col1[indx][cumsum(indx)]
df
# Col1 Col2
#1 Name1 Data
#2 Name1 Data
#3 Name1 Data
#4 Name2 Data
#5 Name2 Data
#6 Name2 Data
df <- structure(list(Col1 = c("Name1", NA, NA, "Name2", NA, NA),
Col2 = c("Data", "Data", "Data", "Data", "Data", "Data")), .Names = c("Col1",
"Col2"), class = "data.frame", row.names = c(NA, -6L))
答案 1 :(得分:2)
我非常喜欢@ akrun的答案,非常聪明!我可能会在将来尝试切换到该方法。另一个选项是zoo::na.locf
,( locf 代表最后一次观察结转)。使用akrun的数据
> df$Col1 <- zoo::na.locf(df$Col1)
> df
Col1 Col2
1 Name1 Data
2 Name1 Data
3 Name1 Data
4 Name2 Data
5 Name2 Data
6 Name2 Data
na.locf
有一些功能可以帮助它在各种情况下工作...如何处理领先的NA
,你可以向后而不是向前,以及其他一些特殊的处理程序(见?na.locf
)。
(数据)
df <- structure(list(Col1 = c("Name1", NA, NA, "Name2", NA, NA),
Col2 = c("Data", "Data", "Data", "Data", "Data", "Data")), .Names = c("Col1",
"Col2"), class = "data.frame", row.names = c(NA, -6L))
答案 2 :(得分:1)
以下是使用Reduce
函数的另一种方法:
> df <- structure(list(Col1 = c("Name1", NA, NA, "Name2", NA, NA),
+ Col2 = c("Data", "Data", "Data", "Data", "Data", "Data")), .Names = c("Col1",
+ "Col2"), class = "data.frame", row.names = c(NA, -6L))
>
> df
Col1 Col2
1 Name1 Data
2 <NA> Data
3 <NA> Data
4 Name2 Data
5 <NA> Data
6 <NA> Data
> df$Col1 <- Reduce(function(a,b) if(is.na(b)) a else b, df$Col1,
+ accumulate=TRUE)
> df
Col1 Col2
1 Name1 Data
2 Name1 Data
3 Name1 Data
4 Name2 Data
5 Name2 Data
6 Name2 Data
>