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不起作用