Я хочу подсчитать каждое вхождение значения / символа в каждой строке кадра данных в R, включая, когда он окружен другими значениями / символами - PullRequest
2 голосов
/ 14 июня 2019

Я прочитал в листе Excel как фрейм данных, который содержит различные цифры и символы в каждой строке / столбце (с некоторыми NA).Для каждой строки я хочу посчитать, например, сколько вхождений «g».Моя проблема в том, что некоторые ячейки содержат что-то вроде «g #» или «ga» или «1g» и, таким образом, не включаются в подсчет.Я хочу посчитать КАЖДЫЕ вхождения g, независимо от того, что находится в ячейке с ним, и затем добавить это число в качестве новой переменной в текущий фрейм данных.

Я попытался возиться со следующим кодом, всекоторые работают для подсчета каждого вхождения ТОЧНО "g", но не просто каждого вхождения "g".

Я догадываюсь, что я ищу регулярное выражение для размещения в любом из следующих кодов.(Я искал несколько часов безрезультатно.) Я также пробовал функции из пакета stringr, такие как str_count, но, похоже, они применимы только к векторам.

oneelecsheet$countg <- rowSums(oneelecsheet == "g", na.rm = TRUE)

library(expss)
oneelecsheet$countg <- count_row_if("g", oneelecsheet)

oneelecsheet$countg <- apply(oneelecsheet, 1, function(x) length(which(x=="g")))

library(dplyr)
oneelecsheet$countg <- apply(oneelecsheet, 1, function(x) sum(x %in% "g"))

Ответы [ 2 ]

3 голосов
/ 14 июня 2019

Если в ячейке есть несколько вхождений "g", как бы вы подсчитали это?Например, если есть слово с именем "ageeg", будет ли ему подсчитано 1 или 2?Основываясь на ответе на этот вопрос, вы можете использовать любое из следующего.

1) Если на ячейку нужно сосчитать только один "g"

df$gcount <- colSums(apply(df, 1, grepl, pattern = "g"))

df
#       a     b gcount
#1 abcg#g  good      2
#2     gg   bad      1
#3     g@  ugly      2
#4  abcdg ageeg      2

Если мы хотим избежать apply, мы можем использовать

rowSums(sapply(df, grepl, pattern = "g"))

Или(спасибо @thelatemail)

Reduce(`+`, lapply(df, grepl, pattern ="g"))

2) Если каждый "g" должен учитываться отдельно

df$gcount <- colSums(apply(df, 1, stringr::str_count, "g"))

df
#       a     b gcount
#1 abcg#g  good      3
#2     gg   bad      2
#3     g@  ugly      2
#4  abcdg ageeg      3

Здесь мы также можем использовать неприменимые версии

rowSums(sapply(df, stringr::str_count, "g"))

Или

Reduce(`+`, lapply(df, stringr::str_count, "g"))

data

df <- data.frame(a = c("abcg#g", "gg", "g@", "abcdg"),
                 b = c("good", "bad", "ugly", "ageeg"))
0 голосов
/ 14 июня 2019

Мы можем использовать pmap с str_count с tidyverse

library(tidyverse)
df %>% 
    mutate(gcount = pmap_int(., ~ str_count(c(...), "g") %>% 
        sum))
#        a     b gcount
#1 abcg#g  good      3
#2     gg   bad      2
#3     g@  ugly      2
#4  abcdg ageeg      3

или с unite и str_count

df %>% 
   unite(gcount, a, b, remove = FALSE) %>% 
   mutate(gcount = str_count(gcount, "g"))

Или используя base R с gregexpr и lengths

lengths(gregexpr("g", do.call(paste, df)))
#[1] 3 2 2 3

или другой вариант с gsub и nchar

with(df, nchar(gsub("[^g]+", "", paste(a, b))))
#[1] 3 2 2 3

данные

df <- structure(list(a = c("abcg#g", "gg", "g@", "abcdg"), b = c("good", 
"bad", "ugly", "ageeg")), class = "data.frame", row.names = c(NA, 
-4L))
...