我有一个像
这样的数据表 col1 col2 col3 col4
1: a a a 2
2: b b a 4.4
3: w w s 6.3
我希望在没有运行for循环的情况下得到类似下面的东西。
col1 col2 col3 col4 count
1: a a a 2 1
2: b b a 4.4 2
3: w w s 6.3 2
我计算每行中col1,col2,col3的唯一值并存储在count列中。我如何在一行中做到这一点?
答案 0 :(得分:7)
这可能有用:
df <- read.table(header=T, text=' col1 col2 col3 col4
1 a a a 2
2 b b a 4.4
3 w w s 6.3')
#one line using apply
df$count <- apply(df[1:3], 1, function(x) {length(unique(x))})
输出:
> df
col1 col2 col3 col4 count
1 a a a 2.0 1
2 b b a 4.4 2
3 w w s 6.3 2
在此示例中使用data.table
语法会有点棘手。
首先,我创建一个id列,通过该列来分组:
#convert original df to data.table
df2 <- as.data.table(df)
df2[, id := 1:nrow(df2) ]
然后我使用我自制的luna函数来计算独特元素的长度:
luna <- function(x) length(unique(unlist(strsplit(x,''))))
df2[, count := luna(paste0(col1, col2, col3)), by=id ]
输出:
> df2
col1 col2 col3 col4 id count
1: a a a 2.0 1 1
2: b b a 4.4 2 2
3: w w s 6.3 3 2
或者@Tensibai在评论中提到,这要快得多:
df2 <- as.data.table(df)
df2[, id := 1:nrow(df2) ]
luna <- function(x) length(unique(x))
df2[, count2 := luna(c(col1, col2, col3)), by=id ]
> df2
col1 col2 col3 col4 id count2
1: a a a 2.0 1 1
2: b b a 4.4 2 2
3: w w s 6.3 3 2
如果我们将@ Frank和@Tensibai的评论结合起来,这应该是最快的(data.table 1.9.5 +):
df2 <- as.data.table(df)
df2[, id := 1:nrow(df2) ]
#not run
#works only in data.table >= 1.9.5
df2[, count2 := uniqueN(c(col1, col2, col3)), by=id ]
#not run
答案 1 :(得分:0)
以下内容如何:
dt <- CJ(1:5,1:3,1:4,1:2)
dt[, cnt:=apply(dt, 1, function(r) length(unique(r)))]
或者如果您只想保留具有唯一条目的行,可以尝试
dt <- CJ(1:5,1:3,1:4,1:2)
dt[apply(dt, 1, function(r) length(unique(r))==ncol(dt))]