我有data frame
看起来像这样
x <- data.frame("a.1" = c(NA, NA, 101, 101, NA),
"a.2" = c(NA, NA, 101, NA, NA),
"a.3" = c(101, NA, NA, NA, 103),
"a.4" = c(NA, NA , NA, NA, 103))
每行包含NA
&和/或某些10x
值。该值对于每一行是唯一的,因此一行不能包含例如同时101
和103
。
现在我想创建一个包含每行中找到的值的列,无论它是出现一次还是多次。只有NA
的每一行也应该有NA
。在我的情况下,这应该是这样的
new column
1 101
2 NA
3 101
4 101
5 103
知道如何以有效的方式实现这一目标!我的orginial数据框非常大,所以我想避免计算成本高昂的for
- 循环和模糊的ifelse
语句。
提前致谢
修改
@krun指出,使用rowMeans()
是一个非常好的解决方案。但是,在我的原始数据集中,值101,102 ......实际上是表示某个行业的字符串。当然,我可以通过as.numeric
转换它们,但我有一些带有前导零的行业指标,例如013
,0201
等。这些零在转换为数字时会被杀死(逻辑上)因此我无法转换它们。
在这种情况下该怎么办?
答案 0 :(得分:4)
我们可以使用pmax
x$newcolumn <- do.call(pmax, c(x, list(na.rm=TRUE)))
x$newcolumn
#[1] 101 NA 101 101 103
或者另一个选项是rowMeans
,因为一行中只有一个唯一元素。
rowMeans(x, na.rm=TRUE)
如果列为character
类且不想转换为numeric
,则一个选项为max.col
x1[cbind(1:nrow(x1),max.col(!is.na(x1), 'first'))]
#[1] "012" NA "012" "011" "011"
pmax
方法也应该有用
do.call(pmax, c(x1, na.rm=TRUE))
#[1] "012" NA "012" "011" "011"
x1 <- data.frame(a.1 = c(NA, NA, '012', '011', NA),
a.2 = c(NA, NA, '012', NA, NA),
a.3 = c('012', NA, NA, NA, '011'),
a.4 = c(NA, NA , NA, NA, '011'), stringsAsFactors=FALSE)
答案 1 :(得分:1)
好的,我找到了一个使用apply
,lapply
和`ifelse``声明的解决方案...不像我想的那样干净但是它的速度相当快而且有效
x1 <- data.frame(a.1 = c(NA, NA, '012', '011', NA),
a.2 = c(NA, NA, '012', NA, NA),
a.3 = c('012', NA, NA, NA, '011'),
a.4 = c(NA, NA , NA, NA, '011'), stringsAsFactors=FALSE)
new.column <- x1 %>%
apply(1, function(i) unique(i[!is.na(i)])) %>%
lapply(function(i) ifelse(length(i) == 0, NA, i)) %>%
unlist()