how count the number of rows in a dataframe with cell matching each other - r

I have two columns (one with predicted values (in strings) and one with real values (in strings) and my wish is to assess the number of rows in which the real values or string do match the predicted values or string in the same row.
I was wondering whether it is possible to something like that with R?

# create sample dataset
df <- data.frame(
col1 = c("a", "b", "c", "d", "e"),
col2 = c("a", "x", "y", "z", "e"),
stringsAsFactors = FALSE
)
# count the number of rows where two columns equal each other
sum( df$col1 == df$col2 )

Related

R add all combinations of three values of a vector to a three-dimensional array

I have a data frame with two columns. The first one "V1" indicates the objects on which the different items of the second column "V2" are found, e.g.:
V1 <- c("A", "A", "A", "A", "B", "B", "B", "C", "C", "C", "C")
V2 <- c("a","b","c","d","a","c","d","a","b","d","e")
df <- data.frame(V1, V2)
"A" for example contains "a", "b", "c", and "d". What I am looking for is a three dimensional array with dimensions of length(unique(V2)) (and the names "a" to "e" as dimnames).
For each unique value of V1 I want all possible combinations of three V2 items (e.g. for "A" it would be c("a", "b", "c"), c("a", "b", "d", and c("b", "c", "d").
Each of these "three-item-co-occurrences" should be regarded as a coordinate in the three-dimensional array and therefore be added to the frequency count which the values in the array should display. The outcome should be the following array
ar <- array(data = c(0,0,0,0,0,0,0,1,2,1,0,1,0,2,0,0,2,2,0,1,0,1,0,1,0,
0,0,1,2,1,0,0,0,0,0,1,0,0,1,0,2,0,1,0,1,1,0,0,1,0,
0,1,0,2,0,1,0,0,1,0,0,0,0,0,0,2,1,0,0,0,0,0,0,0,0,
0,2,2,0,1,2,0,1,0,1,2,1,0,0,0,0,0,0,0,0,1,1,0,0,0,
0,1,0,1,0,1,0,0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0),
dim = c(5, 5, 5),
dimnames = list(c("a", "b", "c", "d", "e"),
c("a", "b", "c", "d", "e"),
c("a", "b", "c", "d", "e")))
I was wondering about the 3D symmetry of your result. It took me a while to understand that you want to have all permutations of all combinations.
library(gtools) #for the permutations
foo <- function(x) {
#all combinations:
combs <- combn(x, 3, simplify = FALSE)
#all permutations for each of the combinations:
combs <- do.call(rbind, lapply(combs, permutations, n = 3, r = 3))
#tabulate:
do.call(table, lapply(asplit(combs, 2), factor, levels = letters[1:5]))
}
#apply grouped by V1, then sum the results
res <- Reduce("+", tapply(df$V2, df$V1, foo))
#check
all((res - ar)^2 == 0)
#[1] TRUE
I used to use the crossjoin CJ() to retain the pairwise count of all combinations of two different V2 items
res <- setDT(df)[,CJ(unique(V2), unique(V2)), V1][V1!=V2,
.N, .(V1,V2)][order(V1,V2)]
This code creates a data frame res with three columns. V1 and V2 contain the respective items of V2 from the original data frame df and N contains the count (how many times V1 and V2 appear with the same value of V1 (from the original data frame df).
Now, I found that I could perform this crossjoin with three 'dimensions' as well by just adding another unique(V2) and adapting the rest of the code accordingly.
The result is a data frame with four columns. V1, V2, and V3 indicate the original V2 items and N again shows the number of mutual appearances with the same original V1 objects.
res <- setDT(df)[,CJ(unique(V2), unique(V2), unique(V2)), V1][V1!=V2 & V1 != V3 & V2 != V3,
.N, .(V1,V2,V3)][order(V1,V2,V3)]
The advantage of this code is that all empty combinations (those which do not appear at all) are not considered. It worked with 1,000,000 unique values in V1 and over 600 unique items in V2, which would have otherwise caused an extremely large array of 600 x 600 x 600

How to sort a data frame on multiple variables of which the names are given in vectors using a base R function?

I have a data frame like the one below:
df <- data.frame(v1 = c("A", "B", "A", "A", "B", "B", "B", "B", "A", "A", "A", "A"),
v2 = c("X", "Y", "X", "Y", "Z", "X", "X", "Y", "X", "Y", "Z", "Z"),
v3 = c(2, 1, 3, 1, 1, 2, 1, 2, 1, 2, 2, 1))
In this data frame v1 and v2 are so called grouping variables (charachter vectors is this case) within I'd like to order my counter variable v3 ascending using (a) base R function(s). There's no requirement for the order in which the grouping variables are sorted (both ascending and descending would be ok). Now in this special case that would be easy:
df <- df[order(df$v1, df$v2, df$v3),]
Or alternatively:
df <- df[do.call(what = order, args = df),]
What I'd like is a more general solution for any data frame with n grouping variables of which the names are contained in a vector and the name of the counter variable is contained in another vector. Reason I want this is that this data is given in a function call in a user defined function and can therefore vary.
grouping_vars <- c("v1", "v2", ..., "vn") #not actual code. Data frame contains *n* variables.
counter <- "vi" #not actual code. One of them, the i-th, is the counter variable.
Again, I'd like to make use of a base R function here (most likely order) and not a solution from data.frame or tidyverse from example.
Your code is almost there. Just use [] behind df to extract grouping and numerical columns for ordering.
df[do.call(what = order, args = df[,c(grouping_vars, counter)]), ]
PeterD: I added a comma in front of the vector that contains the selected columns to be explicit about the selection of columns of data frame df.

Finding values in a columns "a" which has different values in column "b" for two different data set

Data contains multiple columns and 3000 row
Same OrderNo but different Ordertype.
I want to get all the OrderNo whose Ordertype are different in the two data frame.
I have isolated the two columns from the two data frame and set them in ascending order. Then I tried to use the function cbind to combine the two columns and find the missing values in one of the columns.
xxx <- data.frame( orderNo = c(1:10), Ordertype = c("a", "b", "c", "d", "a", "b", "c", "d", "e", "f"))
yyy <- data.frame( orderNo = c(1:10), Ordertype = c("a", "b", "c", "d", "a", "b", "e", "d", "e", "f"))
In the above example: OrderNo "7" corresponds to "c" in one data frame and "e" in another data frame. I want a set of all such number with a different value in the column Ordertype as my output.
It sounds like you want a data frame that contains differences between two data frames, matched by (and including) orderNo. Is that correct?
One possibility is:
res <- merge(xxx, yyy, by = "orderNo")
res[res[,2] != res[,3], ]
orderNo Ordertype.x Ordertype.y
7 7 c e
Using dplyr and anti_join you can do the following to find differences:
library(dplyr)
inner_join(anti_join(xxx, yyy), anti_join(yyy, xxx), by='orderNo')
orderNo Ordertype.x Ordertype.y
1 7 c e

How to delete all rows with counterparts and the counterparts themselves?

Please, have a look at the following data frame:
df <- data.frame(col1 = c(1, -2, -1, 3, 2 , 2),
col2 = c("a", "b", "a", "c", "b", "b"),
col3 = c("d", "e", "f", "g", "h", "i"))
My goal is to delete all rows in df with negative counterparts and the counterparts themselves. Now, what do I mean by a "negative counterpart"? A row has a negative counterpart if there is another row with the same number in col1 but with a minus, and the same value in col2. The value in col3 does not matter. Rows can have multiple counterparts. In this case, only one of them should be deleted. Thus, in the above example, the final data frame should contain only the fourth and either the fifth or sixth row.
The real df has approx. 4*10^5 rows and 25 columns. Most rows do not have a counterpart. So, my idea was to build a for loop that checks for each row whose value in col1 is less than 0, if there is positive counterpart. But I am struggling with the "checking" part.
for (i in nrow(df)) {
if (df[i, ] < 0) {
# check for positive counterparts here
}
}

Count number of observations with elements in the same order

I am trying to pre-process some data in order to build a Sunburst plot in R. In short, I need to count how many observations have their elements in the same order.
The elements of each observation are character strings. The order does matter.
mylist <- list(c("a", "b", "c"),
c("x", "y"),
c("b", "c", "a"),
c("a", "b", "c"))
Desired output would be something like:
"a-b-c" = 2
"x-y" = 1
"b-c-a" = 1

Resources