基于两列分组值

3

这可能是一个非常简单的问题,但我尝试搜索了一下,但没有找到解决方案。

我有一个包含65列和350万行的庞大数据集。这些数据如下:

GR SR var1 var2 var3 var4 var5 var6 var6

1 2   ""   ""   ""   ""   ""   x    


1  2   x    x    x   ""    ""  ""   

1  2   ""   ""   ""  ""   ""   ""   

1  3   x    x   x   x  "" "" 

1  3   "" ""  "" "" "" ""

"" = NULL的含义是空字符串等同于NULL。

我想根据其他变量更新变量1到6。因此,对于每个GR和SR,如果变量1到变量6包含x,则需要用x进行更新。这将导致以下表格:

GR SR var1 var2 var3 var4 var5 var6

1 2 x x x "" "" x 

1 2 x x x "" "" x 

1 2 x x x "" "" x    

1 3 x x x x "" "" 

1 3 x x x x "" "" 

在我找到这些记录后,我想要删除重复的记录,但是我知道可以使用 library(data.table) 中的 Unique 方法来实现。

有人知道如何做吗?


1
使用 dput(head(data)) 共享数据... - s_baldur
1
""" = NUll" 这部分很令人困惑。您是指 NA 吗?还是字面上的 ""(字符串的 nchar() == 0)? - MichaelChirico
我的意思是,用“”表示这些是空的。 - Qris
nchar(x) == 0 还是 is.na(x) - MichaelChirico
在R中,""仍然是一个字符串,NA表示缺失值,而NULL则是一个空对象。现有的列不太可能包含NULL(除非它是一个列表)。请说明""的含义。 - Darren Tsai
2个回答

阿里云服务器只需要99元/年,新老用户同享,点击查看详情
1
非常容易在data.table语法中完成:
library(data.table)
setDT(my_data)
cols = paste0('var', 1:6)
my_data[ , by = .(GR, SR), 
        (cols) := lapply(.SD, function(x) if (any(x == 'x')) 'x' else '')]
如果我没错的话,您可以简单地删除(cols) :=部分来同时完成两个步骤(即同时获得unique)。
my_data[ , by = .(GR, SR), 
        lapply(.SD, function(x) if (any(x == 'x')) 'x' else '')]

我明白你想做什么,但是我得到了一个“在if (any(X == "X")) "X" else ""中的错误:需要TRUE/FALSE的缺失值”。 - Qris
@Qris,确实你的 "" 不是 "" 而是 NA_character_。尝试在 any 中使用 na.rm = TRUE - MichaelChirico

1

这里有一个解决方案,使用 tidyr 中的 fill() 函数(首先加载 tidyverse):

df %>% group_by(GR, SR) %>%
  fill(starts_with("var")) %>%
  fill(starts_with("var"), .direction = "up")

#      GR    SR var1  var2  var3  var4  var5  var6 
#   <int> <int> <chr> <chr> <chr> <chr> <chr> <chr>
# 1     1     2 x     x     x     NA    NA    x    
# 2     1     2 x     x     x     NA    NA    x    
# 3     1     2 x     x     x     NA    NA    x    
# 4     1     3 x     x     x     x     NA    NA   
# 5     1     3 x     x     x     x     NA    NA 
我猜想空元素是NA。如果它们是字符串"",那么你需要将它们转换为NA,否则上面的代码将无法工作。
# How to recode all "" to NA?
# Insert the following code between group_by() and fill()
mutate_all(funs(na_if(., ""))) %>%

# data
df <- structure(list(GR = c(1L, 1L, 1L, 1L, 1L),
SR = c(2L, 2L, 2L, 3L, 3L), var1 = c(NA, "x", NA, "x", NA),
var2 = c(NA, "x", NA, "x", NA), var3 = c(NA, "x", NA, "x", NA),
var4 = c(NA, NA, NA, "x", NA), var5 = c(NA_character_, NA_character_,
NA_character_, NA_character_, NA_character_), var6 = c("x", NA, NA, NA, NA)),
class = "data.frame", row.names = c(NA, -5L))

请先输入 library(tidyverse),然后再试一次。 - Darren Tsai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,