Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过基于摘要条件替换因子来清除具有空值的dataframe列_R_Grouping_Tidyverse_Missing Data_Mutate - Fatal编程技术网

通过基于摘要条件替换因子来清除具有空值的dataframe列

通过基于摘要条件替换因子来清除具有空值的dataframe列,r,grouping,tidyverse,missing-data,mutate,R,Grouping,Tidyverse,Missing Data,Mutate,我很抱歉标题不清楚,但我不确定如何最好地用文字解释这个问题,我将尝试使用一个例子。我正在使用篮球数据集,其中“位置”列中的某些行具有NAs。我想用该职位当年最接近平均高度的职位来更新职位栏。 以下是一个数据帧示例: df_player <- data.frame(id = 1:100, year = floor(runif(100,2000,2006)), height = runif(10

我很抱歉标题不清楚,但我不确定如何最好地用文字解释这个问题,我将尝试使用一个例子。我正在使用篮球数据集,其中“位置”列中的某些行具有NAs。我想用该职位当年最接近平均高度的职位来更新职位栏。 以下是一个数据帧示例:

df_player <- data.frame(id = 1:100, 
                        year = floor(runif(100,2000,2006)), 
                        height = runif(100,70,85), 
                        pos = sample(c("G","F","C",NA), size = 100, replace = TRUE))

我希望能找到一个类似的tidyverse解决方案,我可以在管道中使用,但非常感谢您提供的任何帮助。

Lappy函数会按年份过滤平均身高数据帧,并找到球员身高和平均身高之间绝对差值最小的位置。如果缺少该位置,则会使用
y
中最近的位置进行更新

library(dplyr)

df_avg <- mutate(df_avg, pos = as.character(pos))

df_player <- df_player %>%
  as_tibble() %>%
  mutate(id = 1:nrow(df_player),
         pos = as.character(pos)) %>%
  split(.$id) %>%
  lapply(function(x, ref) {

    y <- ref %>%
      as_tibble() %>%
      filter(year == x$year) %>%
      mutate(diff = abs(ref[ref$year == x$year, ]$avg_height - as.numeric(x$height))) %>%
      top_n(1, desc(diff))

    mutate(x, pos = ifelse(is.na(pos), y$pos, pos))

  }, ref = df_avg) %>%
  bind_rows() %>%
  select(-id)

lappy
功能按年份过滤平均身高数据帧,并查找球员身高与平均身高之间绝对差值最小的位置。如果缺少该位置,则会使用
y
中最近的位置进行更新

library(dplyr)

df_avg <- mutate(df_avg, pos = as.character(pos))

df_player <- df_player %>%
  as_tibble() %>%
  mutate(id = 1:nrow(df_player),
         pos = as.character(pos)) %>%
  split(.$id) %>%
  lapply(function(x, ref) {

    y <- ref %>%
      as_tibble() %>%
      filter(year == x$year) %>%
      mutate(diff = abs(ref[ref$year == x$year, ]$avg_height - as.numeric(x$height))) %>%
      top_n(1, desc(diff))

    mutate(x, pos = ifelse(is.na(pos), y$pos, pos))

  }, ref = df_avg) %>%
  bind_rows() %>%
  select(-id)

下面是使用
dplyr
和一系列连接的一种方法:

library(dplyr)

df_player %>%
  filter(is.na(pos)) %>%
  left_join(df_avg, by = 'year') %>%
  group_by(id) %>%
  mutate(pos.x = pos.y[which.min(abs(height - avg_height))]) %>%
  filter(!duplicated(id)) %>%
  right_join(df_player) %>%
  mutate(pos = coalesce(pos, pos.x)) %>%
  select(-pos.x, -pos.y, -avg_height)


#      id  year height pos  
#   <int> <dbl>  <dbl> <fct>
# 1     1  2001   74.9 F    
# 2     2  2001   75.8 F    
# 3     3  2003   70.6 G    
# 4     4  2000   75.4 C    
# 5     5  2002   78.6 F    
# 6     6  2002   80.3 G    
# 7     7  2004   84.6 C    
# 8     8  2002   80.5 F    
# 9     9  2003   70.2 C    
#10    10  2001   78.0 F    
# … with 90 more rows
库(dplyr)
df_播放器%>%
过滤器(is.na(pos))%>%
左联合(df_平均值,由='年')%>%
分组依据(id)%>%
变异(pos.x=pos.y[which.min(绝对高度-平均高度)))%>%
筛选器(!重复(id))%>%
右加入(df玩家)%>%
突变(pos=结合(pos,pos.x))%>%
选择(-x位置,-y位置,-平均高度)
#id年高位置
#       
#1 2001 74.9 F
#2 2001 75.8 F
#3 2003 70.6克
#4 2000 75.4 C
#5 2002 78.6 F
#6 2002 80.3克
#7 2004 84.6 C
#8 2002 80.5 F
#9 2003 70.2 C
#10 10 2001 78.0华氏度
#…还有90行
数据

set.seed(100)
df_player <- data.frame(id = 1:100, 
                        year = floor(runif(100,2000,2006)), 
                        height = runif(100,70,85), 
                        pos = sample(c("G","F","C",NA), size = 100, replace = TRUE))
set.seed(100)

df_player这里有一种使用
dplyr
和一系列连接的方法:

library(dplyr)

df_player %>%
  filter(is.na(pos)) %>%
  left_join(df_avg, by = 'year') %>%
  group_by(id) %>%
  mutate(pos.x = pos.y[which.min(abs(height - avg_height))]) %>%
  filter(!duplicated(id)) %>%
  right_join(df_player) %>%
  mutate(pos = coalesce(pos, pos.x)) %>%
  select(-pos.x, -pos.y, -avg_height)


#      id  year height pos  
#   <int> <dbl>  <dbl> <fct>
# 1     1  2001   74.9 F    
# 2     2  2001   75.8 F    
# 3     3  2003   70.6 G    
# 4     4  2000   75.4 C    
# 5     5  2002   78.6 F    
# 6     6  2002   80.3 G    
# 7     7  2004   84.6 C    
# 8     8  2002   80.5 F    
# 9     9  2003   70.2 C    
#10    10  2001   78.0 F    
# … with 90 more rows
库(dplyr)
df_播放器%>%
过滤器(is.na(pos))%>%
左联合(df_平均值,由='年')%>%
分组依据(id)%>%
变异(pos.x=pos.y[which.min(绝对高度-平均高度)))%>%
筛选器(!重复(id))%>%
右加入(df玩家)%>%
突变(pos=结合(pos,pos.x))%>%
选择(-x位置,-y位置,-平均高度)
#id年高位置
#       
#1 2001 74.9 F
#2 2001 75.8 F
#3 2003 70.6克
#4 2000 75.4 C
#5 2002 78.6 F
#6 2002 80.3克
#7 2004 84.6 C
#8 2002 80.5 F
#9 2003 70.2 C
#10 10 2001 78.0华氏度
#…还有90行
数据

set.seed(100)
df_player <- data.frame(id = 1:100, 
                        year = floor(runif(100,2000,2006)), 
                        height = runif(100,70,85), 
                        pos = sample(c("G","F","C",NA), size = 100, replace = TRUE))
set.seed(100)

df_player有很多方法可以做你想做的事情,但是你可能会得到更好的结果,用MICE包输入该列,它将查看高度和其他列以最佳估计位置。考虑到前锋和后卫有着非常相似的手段,允许抢断、篮板和三分球在其中发挥作用,插补更有可能产生更好的估计……为了重复性和清洁性,我只想更新当前的数据框架。为每个位置的平均高度添加一列,并将高度与这些高度进行比较,这是我考虑过的解决方案,但必须有一个更优雅的解决方案。我更希望找到一个类似于我展示的group by和mutate示例的解决方案。感谢您的关注,如果加入是实现这一目标的唯一途径,或者如果您的想法与我的不同,我非常高兴听到解决方案。我以前从未听说过MICE软件包,一定会研究它。谢谢你的建议。你能用这个提供解决方案吗?甚至可能只是提供一个解决方案来解决这个问题?这是一个关于老鼠的教程,它非常复杂,根据我的经验,它比任何均值、中位数或模式插补方法都要精确得多。谢谢你的建议。为了回答具体问题,你有什么解决办法吗?有很多方法可以做到你想要的,但是你可能会得到更好的结果,用MICE软件包输入该列,它将查看高度和其他列以最佳估计位置。考虑到前锋和后卫有着非常相似的手段,允许抢断、篮板和三分球在其中发挥作用,插补更有可能产生更好的估计……为了重复性和清洁性,我只想更新当前的数据框架。为每个位置的平均高度添加一列,并将高度与这些高度进行比较,这是我考虑过的解决方案,但必须有一个更优雅的解决方案。我更希望找到一个类似于我展示的group by和mutate示例的解决方案。感谢您的关注,如果加入是实现这一目标的唯一途径,或者如果您的想法与我的不同,我非常高兴听到解决方案。我以前从未听说过MICE软件包,一定会研究它。谢谢你的建议。你能用这个提供解决方案吗?甚至可能只是提供一个解决方案来解决这个问题?这是一个关于老鼠的教程,它非常复杂,根据我的经验,它比任何均值、中位数或模式插补方法都要精确得多。谢谢你的建议。只是为了回答具体问题,你有什么解决办法吗?谢谢你的回答,我已经确认它是有效的!然而,是否有任何方法可以做到这一点而不必形成中间数据帧df_avg?我提供它只是为了帮助说明这个问题。理想情况下,我希望将一个函数直接映射到类似于我用高度显示的示例的列。谢谢你的回答,我已经确认它是有效的!但是,有没有办法