将列中的na替换为与单独表中的列名对应的值

时间:2016-07-04 02:52:46

标签: r

我有一个看起来像这样的数据框

|x_1|   | 1   x_1  x_2|| 0.7|
|x_2| = |x_1   1   x_1|| 0.5|
|x_3|   |x_2  x_1   1 ||-0.4|

我有一个映射文件,看起来像这样

data <- data.frame(ID = c(1,2,3,4,5),A = c(1,4,NA,NA,4),B = c(1,2,NA,NA,NA),C= c(1,2,3,4,NA))

> data
  ID  A  B  C
1  1  1  1  1
2  2  4  2  2
3  3 NA NA  3
4  4 NA NA  4
5  5  4 NA NA

我希望使用参考文件修改我的数据文件,这样可以产生最终数据框

reference <- data.frame(Names = c("A","B","C"),Vals = c(2,5,6))

> reference
  Names Vals
1     A    2
2     B    5
3     C    6

我能在R中实现这一目标的最快方式是什么?

3 个答案:

答案 0 :(得分:4)

我们可以使用using PROJECT; using PROJECT.UWP; using System.Collections.Generic; using Windows.Devices.Geolocation; using Windows.UI.Xaml.Controls.Maps; using Xamarin.Forms.Maps; using Xamarin.Forms.Maps.UWP; using Xamarin.Forms.Platform.UWP; [assembly: ExportRenderer(typeof(CustomMap), typeof(CustomMapRenderer))] namespace PROJECT.UWP { public class CustomMapRenderer : MapRenderer { MapControl nativeMap; CustomMap formsMap; protected override void OnElementChanged(ElementChangedEventArgs<Map> e) { base.OnElementChanged(e); if (e.OldElement != null) { nativeMap = Control as MapControl; } if (e.NewElement != null) { formsMap = (CustomMap)e.NewElement; nativeMap = Control as MapControl; UpdatePolyLine(); } } protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { base.OnElementPropertyChanged(sender, e); if (this.Element == null || this.Control == null) return; if (e.PropertyName == CustomMap.RouteCoordinatesProperty.PropertyName) { UpdatePolyLine(); } } private void UpdatePolyLine() { if (formsMap != null && formsMap.RouteCoordinates.Count > 0) { List<BasicGeoposition> coordinates = new List<BasicGeoposition>(); foreach (var position in formsMap.RouteCoordinates) { coordinates.Add(new BasicGeoposition() { Latitude = position.Latitude, Longitude = position.Longitude }); } Geopath path = new Geopath(coordinates); MapPolyline polyline = new MapPolyline(); polyline.StrokeColor = Windows.UI.Color.FromArgb(128, 255, 0, 0); polyline.StrokeThickness = 5; polyline.Path = path; nativeMap.MapElements.Add(polyline); } } } }

执行此操作
Map

编辑:基于@ thelatemail的评论。

注意:没有使用外部包

由于我们正在寻找有效的解决方案,另一种方法是来自data[as.character(reference$Names)] <- Map(function(x,y) replace(x, is.na(x), y), data[as.character(reference$Names)], reference$Vals) data # ID A B C #1 1 1 1 1 #2 2 4 2 2 #3 3 2 5 3 #4 4 2 5 4 #5 5 4 5 6 的{​​{1}}

set

注意:只使用一个有效的外部包。

答案 1 :(得分:3)

一种方法是计算捕获哪些单元格为NA的目标列的逻辑矩阵。然后我们可以使用替换值索引分配NA单元格。棘手的部分是确保替换向量与索引单元格对齐:

im <- is.na(data[as.character(reference$Names)]);
data[as.character(reference$Names)][im] <- rep(reference$Vals,colSums(im));
data;
##   ID A B C
## 1  1 1 1 1
## 2  2 4 2 2
## 3  3 2 5 3
## 4  4 2 5 4
## 5  5 4 5 6

答案 2 :(得分:0)

如果reference的格式与data的格式相同,则会为替换coalesce而构建新的(v。0.5.0)NA函数;与purrr一起提供*apply函数的替代符号,它使得过程非常简单:

library(dplyr)

# spread reference to wide, add ID column for mapping
reference_wide <- data.frame(ID = NA_real_, tidyr::spread(reference, Names, Vals))

reference_wide

#   ID A B C
# 1 NA 2 5 6

# now coalesce the two column-wise and return a df
purrr::map2_df(data, reference_wide, coalesce)

# Source: local data frame [5 x 4]
# 
#      ID     A     B     C
#   <dbl> <dbl> <dbl> <dbl>
# 1     1     1     1     1
# 2     2     4     2     2
# 3     3     2     5     3
# 4     4     2     5     4
# 5     5     4     5     6