根据条件更新R dataframe列

根据条件更新R dataframe列,r,dataframe,conditional-statements,R,Dataframe,Conditional Statements,我正在尝试根据特定条件更新数据帧。下面是示例数据帧 fname mname lname 1 RONALD D VALE 2 RONALD VALE 3 JACK A SMITH 4 JACK B SMITH 5 JACK SMITH 如果名字和姓氏匹配,我想更新中间名列。在本例中,我希望得到以下输出 fname mname lname 1 RONALD D VALE 2 RONALD D VALE 3 JACK A SMITH 4

我正在尝试根据特定条件更新数据帧。下面是示例数据帧

  fname mname lname
 1   RONALD D VALE
 2   RONALD  VALE
 3   JACK A SMITH
 4   JACK B SMITH
 5   JACK  SMITH
如果名字和姓氏匹配,我想更新中间名列。在本例中,我希望得到以下输出

  fname mname lname
 1   RONALD D VALE
 2   RONALD D VALE
 3   JACK A SMITH
 4   JACK B SMITH
 5   JACK  SMITH

如果有两个不同的中间首字母,我也不想更新表。数据中缺少一些值。因此,主要目的是识别和合并可能相似的多个条目。同时,我们不希望在表中引入错误数据。

A
tidyverse
解决方案:

df %>% 
  group_by(fname, lname) %>% 
  mutate(mname_count = n_distinct(mname, na.rm = TRUE)) %>%
  mutate(mname = ifelse(mname_count == 1, unique(na.omit(mname)), mname)) %>%
  select(-mname_count)
丑陋的base R解决方案(假设您将
更改为
NA
):


unic我们可以使用
data.table

library(data.table)
setDT(df1)[, mname := if(uniqueN(mname[nzchar(mname)])==1) 
                           mname[nzchar(mname)] else mname, .(fname,  lname)]
df1
#    fname mname lname
#1: RONALD     D  VALE
#2: RONALD     D  VALE
#3:   JACK     A SMITH
#4:   JACK     B SMITH
#5:   JACK       SMITH
数据
df1这不会像示例中那样将空的中间首字母更新为
RONALD D VALE
——我认为这是因为中间名的缺失是空格,而不是NAYeah,我当时的假设是缺少中间首字母的是
NA
,而不是
(这是更好的编码方式),您能否帮助进行另一个查询,以查看fname和lname的每个组合有多少不同的MNAME(包括NA)?我想用它来检查查询是否正确
df%>%group\u by(fname,lname)%%>%summary(n\u distinct(mname))
library(data.table)
setDT(df1)[, mname := if(uniqueN(mname[nzchar(mname)])==1) 
                           mname[nzchar(mname)] else mname, .(fname,  lname)]
df1
#    fname mname lname
#1: RONALD     D  VALE
#2: RONALD     D  VALE
#3:   JACK     A SMITH
#4:   JACK     B SMITH
#5:   JACK       SMITH
df1 <- structure(list(fname = c("RONALD", "RONALD", "JACK", "JACK", 
 "JACK"), mname = c("D", "", "A", "B", ""), lname = c("VALE", 
 "VALE", "SMITH", "SMITH", "SMITH")), .Names = c("fname", "mname", 
 "lname"), class = "data.frame", row.names = c("1", "2", "3", 
 "4", "5"))