R 我需要创建一个变量,在数据集中的一些特定列中选择最接近另一个特定列的列
我有一个与此类似的数据集:R 我需要创建一个变量,在数据集中的一些特定列中选择最接近另一个特定列的列,r,dplyr,R,Dplyr,我有一个与此类似的数据集: data= data.frame(a=c(33,44,55), b= c(99,77,NA,66), var1=c(1,2,3,NA),var2=c(5,6,NA,7),var3=c(8,9,10,NA), x = c(6,5,4,3)) 我需要创建一个列,为每一行指定最接近x列的var1、var2和var3列中的值,忽略var1:var3中的NA 比如: closest_x 5 6 3 7 data %>% mutate(pm
data= data.frame(a=c(33,44,55), b= c(99,77,NA,66),
var1=c(1,2,3,NA),var2=c(5,6,NA,7),var3=c(8,9,10,NA), x = c(6,5,4,3))
我需要创建一个列,为每一行指定最接近x列的var1、var2和var3列中的值,忽略var1:var3中的NA
比如:
closest_x
5
6
3
7
data %>% mutate(pmin = pmin(starts_with("var")))
在我真正的问题中,我有比这更多的列,所以我想使用starts\u with
来选择要与X进行比较的列(上面表示为“var1”的列,等等)
我尝试过用X列和“var”列之间的模块差异来创建列,然后我尝试了以下方法:
closest_x
5
6
3
7
data %>% mutate(pmin = pmin(starts_with("var")))
或
而且
data %>% with(pmin(starts_with("var")))
它表示未设置变量上下文。除此之外,如果我不必用这个模差创建许多其他变量,直接转到与列X最接近的值,那就更好了
我在这篇文章中发现了一些非常接近我需要的东西:
然而,我不知道如何应用类似于我的问题的东西,因为我有更多的列,我只想选择那些以特定单词开头的列
编辑:我需要将变量中的NA与忽略的“x”进行比较
编辑2:使用我的真实数据集的代码在过去工作得很好。现在我试图再次运行它,但它没有正常工作。我试着找出发生了什么变化,甚至是否有任何包发生了变化,但事实似乎并非如此
下面是一段代码,用于生成我的真实数据的小样本。我有ideolparty\u A:ideolparty\u I
,而不是x
(要比较的变量),我有ideol\u self
使用max.col
的解决方案直到几个月前才开始工作,代码如下:
temp_df <- -abs(cses_pr[cols] - cses_pr$ideol_self)
cses_pr$closest <- cses_pr[cols][cbind(1:nrow(cses_pr),
max.col(replace(temp_df, is.na(temp_df), -Inf)))]
下面是一种使用
max.col
cols <- grep("^var", names(data))
data$closest_x <- data[cols][cbind(1:nrow(data),
max.col(-abs(data[cols] - data$x)))]
# a b var1 var2 var3 x closest_x
#1 33 99 24 15 45 11 15
#2 44 77 12 30 27 22 27
#3 55 66 76 20 15 33 20
如果数据中有
NA
值,我们可以将它们替换为-Inf
,然后替换为子集
temp_df <- -abs(data[cols] - data$x)
data$closest_x <- data[cols][cbind(1:nrow(data),
max.col(replace(temp_df, is.na(temp_df), -Inf)))]
temp\u df这里有一种使用max.col
cols <- grep("^var", names(data))
data$closest_x <- data[cols][cbind(1:nrow(data),
max.col(-abs(data[cols] - data$x)))]
# a b var1 var2 var3 x closest_x
#1 33 99 24 15 45 11 15
#2 44 77 12 30 27 22 27
#3 55 66 76 20 15 33 20
如果数据中有NA
值,我们可以将它们替换为-Inf
,然后替换为子集
temp_df <- -abs(data[cols] - data$x)
data$closest_x <- data[cols][cbind(1:nrow(data),
max.col(replace(temp_df, is.na(temp_df), -Inf)))]
temp_df“整洁”方法
一个更“整洁”的解决方案可能是这样的
data %>%
# reshape data to long format w/ row numbers
mutate(row = row_number()) %>%
gather(col, val, starts_with('var')) %>%
# compute the minimum difference row-by-row
group_by(row) %>%
summarize(closest_to_x = val[which.min(abs(val - x))]) %>%
# the next two lines just take the new column and paste it back onto the original data
select(closest_to_x) %>%
bind_cols(data, .)
它有点冗长,但我觉得它相当可读(当然是YMMV)。对性能没有把握。它不使用max.col()
或pmin()
,而是依赖于将数据重新格式化为“整洁”格式,其中您关心的所有列的值都放在一个val
列中 “整洁”的方法
一个更“整洁”的解决方案可能是这样的
data %>%
# reshape data to long format w/ row numbers
mutate(row = row_number()) %>%
gather(col, val, starts_with('var')) %>%
# compute the minimum difference row-by-row
group_by(row) %>%
summarize(closest_to_x = val[which.min(abs(val - x))]) %>%
# the next two lines just take the new column and paste it back onto the original data
select(closest_to_x) %>%
bind_cols(data, .)
它有点冗长,但我觉得它相当可读(当然是YMMV)。对性能没有把握。它不使用max.col()
或pmin()
,而是依赖于将数据重新格式化为“整洁”格式,其中您关心的所有列的值都放在一个val
列中 谢谢。第一个解决方案奏效了,但我忘了提到我缺少的值我希望被忽略。这是不是很难做到,某种“na.rm”的事情?我正试图将这个解决方案与我喜欢的解决方案结合起来。但是某种NA.rm会更好,这样我就不会弄乱数据集了。第二个选项不起作用(“二进制运算符的非数字参数”)。@GuilhermePiresArbache是的,我们可以将它们替换为-Inf
,然后替换为子集。你能检查一下更新后的答案吗?我再次尝试使用这段代码,因为我正在恢复使用它的项目,不幸的是,它不能使用我的真实数据集。请参见上面的编辑。有什么解决办法吗?感谢您的帮助。@guilhermespiresarbache两年后很难记住答案的上下文。将cses\u pr
更改为数据帧,然后重试回答<是的,这就是为什么我试着把所有的东西都放在我的新编辑里。无论如何,我不敢相信这就是问题所在!出于某种原因,其他一些转换使其与data.frame有所不同。非常感谢你!谢谢第一个解决方案奏效了,但我忘了提到我缺少的值我希望被忽略。这是不是很难做到,某种“na.rm”的事情?我正试图将这个解决方案与我喜欢的解决方案结合起来。但是某种NA.rm会更好,这样我就不会弄乱数据集了。第二个选项不起作用(“二进制运算符的非数字参数”)。@GuilhermePiresArbache是的,我们可以将它们替换为-Inf
,然后替换为子集。你能检查一下更新后的答案吗?我再次尝试使用这段代码,因为我正在恢复使用它的项目,不幸的是,它不能使用我的真实数据集。请参见上面的编辑。有什么解决办法吗?感谢您的帮助。@guilhermespiresarbache两年后很难记住答案的上下文。将cses\u pr
更改为数据帧,然后重试回答<是的,这就是为什么我试着把所有的东西都放在我的新编辑里。无论如何,我不敢相信这就是问题所在!出于某种原因,其他一些转换使其与data.frame有所不同。非常感谢你!谢谢是否有一种方法可以在忽略NAs(请检查我的编辑)时实现此功能?which.min()
默认忽略NAs。此代码仍适用于您编辑的数据。抱歉,回答此问题花费了太长时间。但是这段代码不适用于我的真实数据(参见上面的编辑)。它可以很好地处理示例数据。我收到了类似“错误:无法回收.1
(尺寸4)以匹配.2
(尺寸38390)”的警告。谢谢。是否有一种方法可以在忽略NAs(请检查我的编辑)时实现此功能?which.min()
默认忽略NAs。此代码仍适用于您编辑的数据。抱歉,回答此问题花费了太长时间。但是这个代码对我的真实d不起作用